| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- namespace Day21;
- public class Map
- {
- private readonly int _width;
- private readonly int _height;
- private readonly Tile[,] _map;
- private readonly Tile? _start;
- public Map(int width, int height, IEnumerable<Tile> tiles)
- {
- _width = width;
- _height = height;
- _map = new Tile[width, height];
- var i = 0;
- foreach (var t in tiles)
- {
- if (t.IsStart)
- {
- _start = t;
- }
- t.Position = new Vec(i % width, i / width);
- _map[t.Position.X, t.Position.Y] = t;
- i++;
- }
- if (_start == null)
- {
- throw new Exception("No start tile found");
- }
- }
- public void Print(ISet<Vec>? mark = null)
- {
- for (int y = 0; y < _height; y++)
- {
- for (int x = 0; x < _width; x++)
- {
- if (mark != null && mark.Contains(new Vec(x, y)))
- {
- Console.Write('O');
- }
- else
- {
- Console.Write(_map[x, y]);
- }
- }
- Console.WriteLine();
- }
- Console.WriteLine();
- }
- public long ReachableTiles(int steps)
- {
- var reachable = new HashSet<Vec>();
- reachable.Add(_start!.Position);
-
- for (int i = 0; i < steps; i++)
- {
- var next = new HashSet<Vec>();
- foreach (var p in reachable)
- {
- foreach (var neighbor in Surrounding(p).Where(n => At(n)?.IsWalkable ?? false))
- {
- next.Add(neighbor);
- }
- }
- reachable = next;
- }
-
- Print(reachable);
- return reachable.Count;
- }
- private IEnumerable<Vec> Surrounding(Vec middle)
- {
- yield return middle.Add(ScreenSpace.Up);
- yield return middle.Add(ScreenSpace.Right);
- yield return middle.Add(ScreenSpace.Down);
- yield return middle.Add(ScreenSpace.Left);
- }
- private Tile? At(Vec p)
- {
- if (p.X < 0 || p.X >= _width || p.Y < 0 || p.Y >= _height)
- {
- return null;
- }
- return _map[p.X, p.Y];
- }
- }
|