using System.Drawing; using Day17; namespace Day18; public class Field { private int _minX, _maxX = 0; private int _minY, _maxY = 0; private Vec _pos = new Vec(0, 0); private readonly Dictionary _grid = new Dictionary(); public Field() { _grid[_pos] = new CellData(Color.White); } public void Apply(Instruction inst) { var v = Vec.Direction(inst.Dir); for (var i = 0; i < inst.Num; i++) { _grid[_pos].Outgoing = v; _pos = _pos.Add(v); _grid.TryAdd(_pos, new CellData(inst.Color)); _grid[_pos].Incoming = v; _minX = Math.Min(_minX, _pos.X); _maxX = Math.Max(_maxX, _pos.X); _minY = Math.Min(_minY, _pos.Y); _maxY = Math.Max(_maxY, _pos.Y); } } public int Fill() { var count = 0; for (var y = _minY; y < _maxY + 1; y++) { var lastCorner = 0; var transitions = 0; for (var x = _minX; x < _maxX + 1; x++) { var v = new Vec(x, y); if (_grid.TryGetValue(v, out CellData? d)) { var data = d!; count++; var cornerNum = data.CornerNum(); if (cornerNum == 0) { if (data.Incoming!.Value.IsVertical) { transitions++; } } else { if (lastCorner == 0) { lastCorner = cornerNum; } else if (lastCorner == -cornerNum) { transitions++; lastCorner = 0; } else { lastCorner = 0; } } } else { if (transitions % 2 == 1) { count++; } } } } return count; } private int CornerNum(Vec vec) { var above = _grid.ContainsKey(vec.Add(new Vec(0, -1))); var below = _grid.ContainsKey(vec.Add(new Vec(0, 1))); return above == below ? 0 : above ? -1 : 1; } public void Print() { for (var y = _minY; y < _maxY + 1; y++) { for (var x = _minX; x < _maxX + 1; x++) { if (_grid.ContainsKey(new Vec(x, y))) { Console.Write('#'); } else { Console.Write('.'); } } Console.WriteLine(); } Console.WriteLine(); } private class CellData { public Color Color { get; } public Vec? Outgoing { get; set; } public Vec? Incoming { get; set; } public CellData(Color color) { Color = color; } public int CornerNum() { if (Incoming != null && Outgoing != null) { var n = Incoming.Value.Cross(Outgoing.Value); return Math.Abs(n) == 1 ? n : 0; } return 0; } } }