1
0
Fork 0
advent-of-code/2021/day4.cs

122 lines
3 KiB
C#

var boards = new List<Board>();
using var sr = new StreamReader("../inputs/day04.txt");
var lines = sr.ReadToEnd().Split("\n").Select(x => x.Trim()).ToList();
var numbers = lines.First().Split(",").Select(x => Convert.ToByte(x)).ToList();
lines.RemoveAt(0); //Drop numbers
lines.RemoveAt(0); //Drop whitespace
var currentBoard = new List<string>();
foreach (var line in lines)
{
if (!string.IsNullOrEmpty(line))
{
currentBoard.Add(line);
}
else
{
boards.Add(new Board(currentBoard));
currentBoard = new List<string>();
}
}
var part1Done = false;
foreach (var number in numbers)
{
foreach (var board in boards)
board.Mark(number);
var winningBoards =
boards.Where(board => board.Win).ToArray(); // Need to enumerate this before the loop or it will break
foreach (var board in winningBoards)
{
if (!part1Done)
{
Console.WriteLine($"2021 Day 04 Part 1 result: {board.Score * number}");
part1Done = true;
}
if (boards.Count == 1)
Console.WriteLine($"2021 Day 04 Part 2 result: {board.Score * number}");
boards.Remove(board);
}
if (!boards.Any())
break;
}
private class Board
{
private readonly byte?[,] _rows;
internal int Score => _rows.Cast<byte?>().Aggregate(0, (score, number) => score + (number ?? 0));
private bool HorizontalWin => DidRowWin(_rows);
private bool VerticalWin => DidRowWin(Transpose());
internal bool Win => HorizontalWin || VerticalWin;
internal Board(IEnumerable<string> inputRows)
{
_rows = new byte?[5, 5];
for (var r = 0; r < inputRows.Count(); r++)
{
var nums = inputRows
.ElementAt(r)
.Split(" ")
.Where(x => !string.IsNullOrEmpty(x))
.Select(x => Convert.ToByte(x));
for (var c = 0; c < nums.Count(); c++)
{
_rows[c, r] = nums.ElementAt(c);
}
}
}
internal void Mark(byte number)
{
for (var r = 0; r < _rows.GetLength(0); r++)
{
for (var c = 0; c < _rows.GetLength(1); c++)
{
if (_rows[c, r].HasValue && _rows[c, r].Value == number)
_rows[c, r] = null;
}
}
}
private byte?[,] Transpose()
{
var cols = new byte?[5, 5];
for (var c = 0; c < 5; c++)
{
for (var r = 0; r < 5; r++)
{
cols[c, r] = _rows[r, c];
}
}
return cols;
}
private static bool DidRowWin(byte?[,] rows)
{
var win = true;
for (var r = 0; r < rows.GetLength(0); r++)
{
win = true;
for (var c = 0; c < rows.GetLength(1); c++)
{
if (rows[c, r].HasValue)
win = false;
}
if (win)
break;
}
return win;
}
}