151 lines
4.3 KiB
C#
151 lines
4.3 KiB
C#
// See https://aka.ms/new-console-template for more information
|
|
using AdventCommon;
|
|
|
|
int p1exampleSln = Part01("example-input.txt");
|
|
int p1puzzleSln = Part01("puzzle-input.txt");
|
|
|
|
Console.WriteLine("Part01 Example Points: " + p1exampleSln);
|
|
Console.WriteLine("Part01 Puzzle Points: " + p1puzzleSln);
|
|
|
|
int p2exampleSln = Part02("example-input.txt");
|
|
int p2puzzleSln = Part02("puzzle-input.txt");
|
|
|
|
Console.WriteLine("Part02 Example Points: " + p2exampleSln);
|
|
Console.WriteLine("Part02 Puzzle Points: " + p2puzzleSln);
|
|
|
|
int Part01(string fileName)
|
|
{
|
|
var input = new Day04Input(fileName);
|
|
|
|
int sum = 0;
|
|
foreach (var c in input.Cards)
|
|
{
|
|
sum += c.Points;
|
|
}
|
|
|
|
return sum;
|
|
}
|
|
|
|
int Part02(string fileName)
|
|
{
|
|
var input = new Day04Input(fileName);
|
|
|
|
Dictionary<int, int> CardCopies = new Dictionary<int, int>();
|
|
|
|
// Initial state -- 1 of each
|
|
for (int i = 0; i < input.Cards.Count; i++)
|
|
{
|
|
CardCopies.Add(i + 1, 1);
|
|
}
|
|
|
|
// Start with card 1 and work to the end
|
|
for (int i = 0; i < input.Cards.Count; i++)
|
|
{
|
|
Day04Input.Card card = input.GetCardNumber(i + 1);
|
|
int numberOfCards = CardCopies[i + 1];
|
|
var matches = card.MatchingNumbers;
|
|
|
|
for (int cardNum = 0; cardNum < numberOfCards; cardNum++)
|
|
{
|
|
for (int j = 0; j < matches.Count; j++)
|
|
{
|
|
CardCopies[i + 2 + j]++;
|
|
}
|
|
}
|
|
}
|
|
|
|
int sum = 0;
|
|
foreach (var c in CardCopies)
|
|
{
|
|
sum += c.Value;
|
|
}
|
|
|
|
return sum;
|
|
}
|
|
|
|
class Day04Input : PuzzleInput
|
|
{
|
|
public class Card
|
|
{
|
|
public List<int> WinningNumbers { get; private set; } = new List<int>();
|
|
public List<int> ScratchedNumbers { get; private set; } = new List<int> ();
|
|
public int CardNumber { get; private set; }
|
|
|
|
public Card(string line)
|
|
{
|
|
// Extract card number
|
|
CardNumber = Int32.Parse(line.Split(':', StringSplitOptions.RemoveEmptyEntries)[0].Split(' ', StringSplitOptions.RemoveEmptyEntries)[1]);
|
|
|
|
// extract numbers
|
|
string winningNumbers = line.Split(":")[1].Split('|', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)[0];
|
|
string scratchedNumbers = line.Split(":")[1].Split('|', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)[1];
|
|
|
|
// parse the winning numbers
|
|
foreach (var winningNumber in winningNumbers.Split(' ', StringSplitOptions.RemoveEmptyEntries))
|
|
{
|
|
WinningNumbers.Add(Int32.Parse(winningNumber));
|
|
}
|
|
|
|
// parse the scratchers
|
|
foreach (var scratchedNumber in scratchedNumbers.Split(' ', StringSplitOptions.RemoveEmptyEntries))
|
|
{
|
|
ScratchedNumbers.Add(Int32.Parse(scratchedNumber));
|
|
}
|
|
}
|
|
|
|
public int Points
|
|
{
|
|
get
|
|
{
|
|
int points = 0;
|
|
|
|
foreach (var scratched in ScratchedNumbers)
|
|
{
|
|
if (WinningNumbers.Contains(scratched))
|
|
{
|
|
if (points == 0) points = 1;
|
|
else points *= 2;
|
|
}
|
|
}
|
|
|
|
return points;
|
|
}
|
|
}
|
|
|
|
public List<int> MatchingNumbers
|
|
{
|
|
get
|
|
{
|
|
List<int> matches = new List<int>();
|
|
|
|
foreach (var scratched in ScratchedNumbers)
|
|
{
|
|
if (WinningNumbers.Contains(scratched))
|
|
{
|
|
matches.Add(scratched);
|
|
}
|
|
}
|
|
|
|
return matches;
|
|
}
|
|
}
|
|
}
|
|
|
|
public List<Card> Cards { get; private set; } = new List<Card>();
|
|
|
|
public Card GetCardNumber(int num)
|
|
{
|
|
if (Cards[num - 1].CardNumber != num) throw new InvalidDataException();
|
|
|
|
return Cards[num - 1];
|
|
}
|
|
|
|
public Day04Input(string fileName)
|
|
: base(fileName)
|
|
{
|
|
foreach (var line in Lines)
|
|
{
|
|
Cards.Add(new Card(line));
|
|
}
|
|
}
|
|
} |