using System.Text; namespace Day10; public class Grid { private readonly int _width; private readonly int _height; private Tile? _start; public Tile?[,] Tiles { get; } public Grid(Tile?[,] tiles, int width, int height) { _width = width; _height = height; Tiles = tiles; } public void Print() { for (var y = 0; y < _height; y++) { var lineBuilder = new StringBuilder(); for (var x = 0; x < _width; x++) { lineBuilder.Append(Tiles[x, y]?.Display ?? " "); } Console.WriteLine(lineBuilder); } } public int Follow() { foreach (var t in Tiles) { if (t?.Pipe == 'S') { _start = t; break; } } if (_start == null) { throw new Exception("Start is not set yet"); } var queue = new Queue<(Tile Tile, GridPoint Source, int Index)>(); var num = 0; queue.Enqueue((_start, _start.Position, 0)); while (queue.Count > 0) { var (tile, source, index) = queue.Dequeue(); if (tile.HasDisplay) { return index; } foreach (var next in tile.GetConnections() .Where(n => n != source) .Select(x => this[x]) .Where(t => t?.ConnectsTo(tile.Position) ?? false)) { queue.Enqueue((next!, tile.Position, index + 1)); } tile.SetDisplay(index); num++; if (num % 100 == 0) { Print(); Console.WriteLine(); } } throw new Exception("No cycle found"); } public Tile? this[GridPoint point] { get { if (point.X < 0 || point.Y < 0 || point.X >= _width || point.Y >= _height) { return null; } return Tiles[point.X, point.Y]; } } }