2021aoc/Day4.cs

64 lines
2.0 KiB
C#

// #define Day4
#if Day4
using AoC2021;
var parts = File.ReadAllText("day4/input").Split("\n\n");
var numbers = parts[0].Split(",").Select(int.Parse);
var boards = parts.Skip(1).Select(ToBoard).ToList();
int numberOfBoards = boards.Count;
foreach (var num in numbers) {
var won = boards.Select((board, i) => new {bingo = CheckBoard(num, board), index = i}).Where(a => a.bingo).ToList();
// For PartTwo
if (won.Count > 0 && boards.Count == 1) {
int[,] winningBoard = boards[won.First().index];
CalculateScore(winningBoard, num);
break;
}
if (won.Count > 0 && boards.Count == numberOfBoards) {
int[,] winningBoard = boards[won.First().index];
CalculateScore(winningBoard, num);
}
var wonIndices = won.Select(w => w.index).ToHashSet();
boards = boards.Where((board, index) => !wonIndices.Contains(index)).ToList();
}
void CalculateScore(int[,] board, int lastNum) {
long sum = 0;
for (int row = 0; row < 5; row++) {
for (int col = 0; col < 5; col++) {
if (board[row, col] >= 0) {
sum += board[row, col];
}
}
}
Console.WriteLine(sum * lastNum);
}
bool CheckBoard(int num, int[,] board) {
bool bingo = false;
for (int row = 0; row < 5; row++) {
for (int col = 0; col < 5; col++) {
if (board[row, col] == num) {
board[row, col] *= -1;
bingo |= CheckRow(board, row) || CheckCol(board, col);
}
}
}
return bingo;
}
bool CheckRow(int[,] board, int row) => Enumerable.Range(0, 5).All(col => board[row, col] < 0);
bool CheckCol(int[,] board, int col) => Enumerable.Range(0, 5).All(row => board[row, col] < 0);
int[,] ToBoard(string s) {
int[,] board = new int[5,5];
s.Split("\n")
.ForEachIndex((l, row) => l.Split(" ", StringSplitOptions.RemoveEmptyEntries)
.ForEachIndex((num, col)=>
board[row,col] = Int32.Parse(num)));
return board;
}
#endif