|
@@ -0,0 +1,143 @@
|
|
|
|
|
+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<Vec, CellData> _grid = new Dictionary<Vec, CellData>();
|
|
|
|
|
+
|
|
|
|
|
+ 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;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|