Grid.cs 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. using System.Text;
  2. namespace Day10;
  3. public class Grid
  4. {
  5. private readonly int _width;
  6. private readonly int _height;
  7. private Tile? _start;
  8. public Tile?[,] Tiles { get; }
  9. public Grid(Tile?[,] tiles, int width, int height)
  10. {
  11. _width = width;
  12. _height = height;
  13. Tiles = tiles;
  14. }
  15. public void Print()
  16. {
  17. for (var y = 0; y < _height; y++)
  18. {
  19. var lineBuilder = new StringBuilder();
  20. for (var x = 0; x < _width; x++)
  21. {
  22. lineBuilder.Append(Tiles[x, y]?.Display ?? " ");
  23. }
  24. Console.WriteLine(lineBuilder);
  25. }
  26. }
  27. public int Follow()
  28. {
  29. foreach (var t in Tiles)
  30. {
  31. if (t?.Pipe == 'S')
  32. {
  33. _start = t;
  34. break;
  35. }
  36. }
  37. if (_start == null)
  38. {
  39. throw new Exception("Start is not set yet");
  40. }
  41. var queue = new Queue<(Tile Tile, GridPoint Source, int Index)>();
  42. var num = 0;
  43. queue.Enqueue((_start, _start.Position, 0));
  44. while (queue.Count > 0)
  45. {
  46. var (tile, source, index) = queue.Dequeue();
  47. if (tile.HasDisplay)
  48. {
  49. return index;
  50. }
  51. foreach (var next in tile.GetConnections()
  52. .Where(n => n != source)
  53. .Select(x => this[x])
  54. .Where(t => t?.ConnectsTo(tile.Position) ?? false))
  55. {
  56. queue.Enqueue((next!, tile.Position, index + 1));
  57. }
  58. tile.SetDisplay(index);
  59. num++;
  60. if (num % 100 == 0)
  61. {
  62. Print();
  63. Console.WriteLine();
  64. }
  65. }
  66. throw new Exception("No cycle found");
  67. }
  68. public Tile? this[GridPoint point]
  69. {
  70. get
  71. {
  72. if (point.X < 0 || point.Y < 0 || point.X >= _width || point.Y >= _height)
  73. {
  74. return null;
  75. }
  76. return Tiles[point.X, point.Y];
  77. }
  78. }
  79. }