namespace Day18; public class Field { private CellData[,]? _grid; private long _perimeter = 0L; public void Apply(List instructions) { var pos = new Vec(0, 0); var lines = new List(); _perimeter = 0L; foreach (var inst in instructions) { var line = new Line(pos, Vec.Direction(inst.Dir), inst.Num); lines.Add(line); pos = pos.Add(line.Dir.Multiply(line.Length)); _perimeter += line.Length; } var xNodes = lines.Select(l => l.Start.X).Order().Distinct().ToArray(); var yNodes = lines.Select(l => l.Start.Y).Order().Distinct().ToArray(); _grid = new CellData[xNodes.Length - 1, yNodes.Length - 1]; for (var y = 0; y < yNodes.Length - 1; y++) { for (var x = 0; x < xNodes.Length - 1; x++) { var topLeft = new Vec(xNodes[x], yNodes[y]); var bottomRight = new Vec(xNodes[x + 1], yNodes[y + 1]); var cell = new CellData(topLeft, bottomRight); _grid[x, y] = cell; cell.Lines = lines .Where(l => l.Dir.IsVertical && l.Start.X == topLeft.X) .ToList(); cell.Calculate(); } } } public long GetArea() { if (_grid == null) { throw new NullReferenceException("_grid"); } var count = 0L; for (var y = 0; y < _grid.GetLength(1); y++) { var crossings = 0; for (var x = 0; x < _grid.GetLength(0); x++) { var cell = _grid[x, y]; crossings += cell.HasCrossing ? 1 : 0; if (crossings % 2 == 1) { count += cell.Size(); } } } count += _perimeter / 2 + 1; return count; } public void Print() { if (_grid == null) { throw new NullReferenceException("_grid"); } for (var y = 0; y < _grid.GetLength(1); y++) { var crossings = 0; for (var x = 0; x < _grid.GetLength(0); x++) { var cell = _grid[x, y]; crossings += cell.HasCrossing ? 1 : 0; if (crossings % 2 == 1) { Console.Write('#'); } else { Console.Write('.'); } } Console.WriteLine(); } Console.WriteLine(); } }