public Challenge() { _map = new CharMap(inputList.ToArray()); Dictionary <string, (Point a, Point b)> portals = new Dictionary <string, (Point, Point)>(); void CheckPortal(char c, Point pos, Point dir) { char c2 = _map.GetCharOrDefault(pos + dir); if (!IsPortalID(c2)) { return; } Point portal = _map.GetCharOrDefault(pos - dir) == '.' ? pos - dir : pos + dir * 2; string id = $"{c}{c2}"; switch (id) { case "AA": _map[portal] = 's'; _start = portal; break; case "ZZ": _map[portal] = 'e'; _end = portal; break; default: _map[portal] = IsOuterPortal(portal) ? '@' : '$'; if (!portals.ContainsKey(id)) { portals[id] = (portal, Point.zero); } else { portals[id] = (portals[id].a, portal); } break; } } foreach ((int x, int y, char c) in _map) { if (IsPortalID(c)) { CheckPortal(c, new Point(x, y), Direction.Right); CheckPortal(c, new Point(x, y), Direction.Down); } } foreach ((Point a, Point b) in portals.Values) { _portalMap.Add(a, b); } }
private int FindShortestPath() { int GetH(Point p, Point end) => 0; // No heuristic (Dijsktra's/BFS) bool IsValid(Point p) => ".se@$".Contains(_map.GetCharOrDefault(p)); HashSet <Point> GetNeighbors(Point p) { HashSet <Point> neighbors = new HashSet <Point> { p + new Point(1, 0), p + new Point(0, 1), p + new Point(-1, 0), p + new Point(0, -1) }; if ("@$".Contains(_map[p])) { neighbors.Add(_portalMap[p]); } return(neighbors); } return(Pathfinder.FindPath(_start, _end, IsValid, GetH, GetNeighbors).Count); }