namespace Day17; public class Map { private readonly Tile[,] _tiles; private readonly int _width; private readonly int _height; public Map(Tile[,] tiles, int width, int height) { _tiles = tiles; _width = width; _height = height; } public void Print() { for (var y = 0; y < _height; y++) { for (var x = 0; x < _width; x++) { Console.Write(_tiles[x, y].Display); } Console.WriteLine(); } Console.WriteLine(); } public int ShortestPath() { var n = 0; var goal = _tiles[_width - 1, _height - 1]; var visited = new HashSet(); var queue = new PriorityQueue(); queue.Enqueue(new Path(null, _tiles[0, 0], new Vec(1, 0)), 0); queue.Enqueue(new Path(null, _tiles[0, 0], new Vec(0, 1)), 0); while (queue.Count > 0) { var current = queue.Dequeue(); var curKey = current.GetKey(); if (!visited.Add(curKey)) { continue; } foreach (var v in current.Next()) { var pos = current.Tile.Position.Add(v); if (IsValid(pos)) { var next = new Path(current, Tile(pos), v); if (next.Tile == goal) { var cost = Backtrack(next); return cost; } queue.Enqueue(next, next.Cost); } } if (n % 100 == 0) { Console.WriteLine($"Queue: {queue.Count}"); } n++; } return -1; } private int Backtrack(Path path) { var sum = 0; while (path.Prev != null) { sum += path.Tile.Cost; path.Tile.SetDisplay(path.VRun.Arrow()); path = path.Prev; } return sum; } private bool IsValid(Vec position) { return position.X >= 0 && position.X < _width && position.Y >= 0 && position.Y < _height; } private Tile Tile(Vec position) { return _tiles[position.X, position.Y]; } }