Files
AdventOfCode/2023/Day04CSharp/Program.cs
2025-11-30 20:28:10 -05:00

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));
}
}
}