// #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