Field.cs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. namespace Day18;
  2. public class Field
  3. {
  4. private CellData[,]? _grid;
  5. private long _perimeter = 0L;
  6. public void Apply(List<Instruction> instructions)
  7. {
  8. var pos = new Vec(0, 0);
  9. var lines = new List<Line>();
  10. _perimeter = 0L;
  11. foreach (var inst in instructions)
  12. {
  13. var line = new Line(pos, Vec.Direction(inst.Dir), inst.Num);
  14. lines.Add(line);
  15. pos = pos.Add(line.Dir.Multiply(line.Length));
  16. _perimeter += line.Length;
  17. }
  18. var xNodes = lines.Select(l => l.Start.X).Order().Distinct().ToArray();
  19. var yNodes = lines.Select(l => l.Start.Y).Order().Distinct().ToArray();
  20. _grid = new CellData[xNodes.Length - 1, yNodes.Length - 1];
  21. for (var y = 0; y < yNodes.Length - 1; y++)
  22. {
  23. for (var x = 0; x < xNodes.Length - 1; x++)
  24. {
  25. var topLeft = new Vec(xNodes[x], yNodes[y]);
  26. var bottomRight = new Vec(xNodes[x + 1], yNodes[y + 1]);
  27. var cell = new CellData(topLeft, bottomRight);
  28. _grid[x, y] = cell;
  29. cell.Lines = lines
  30. .Where(l => l.Dir.IsVertical && l.Start.X == topLeft.X)
  31. .ToList();
  32. cell.Calculate();
  33. }
  34. }
  35. }
  36. public long GetArea()
  37. {
  38. if (_grid == null)
  39. {
  40. throw new NullReferenceException("_grid");
  41. }
  42. var count = 0L;
  43. for (var y = 0; y < _grid.GetLength(1); y++)
  44. {
  45. var crossings = 0;
  46. for (var x = 0; x < _grid.GetLength(0); x++)
  47. {
  48. var cell = _grid[x, y];
  49. crossings += cell.HasCrossing ? 1 : 0;
  50. if (crossings % 2 == 1)
  51. {
  52. count += cell.Size();
  53. }
  54. }
  55. }
  56. count += _perimeter / 2 + 1;
  57. return count;
  58. }
  59. public void Print()
  60. {
  61. if (_grid == null)
  62. {
  63. throw new NullReferenceException("_grid");
  64. }
  65. for (var y = 0; y < _grid.GetLength(1); y++)
  66. {
  67. var crossings = 0;
  68. for (var x = 0; x < _grid.GetLength(0); x++)
  69. {
  70. var cell = _grid[x, y];
  71. crossings += cell.HasCrossing ? 1 : 0;
  72. if (crossings % 2 == 1)
  73. {
  74. Console.Write('#');
  75. }
  76. else
  77. {
  78. Console.Write('.');
  79. }
  80. }
  81. Console.WriteLine();
  82. }
  83. Console.WriteLine();
  84. }
  85. }