from collections import deque from lib import get_data from lib import Grid2D data = """############### #...#...#.....# #.#.#.#.#.###.# #S#...#.#.#...# #######.#.#.### #######.#.#...# #######.#.###.# ###..E#...#...# ###.#######.### #...###...#...# #.#####.#.###.# #.#...#.#.#...# #.#.#.#.#.#.### #...#...#...### ############### """ data = get_data(__file__) g = Grid2D(data) (start,) = g.find("S") (end,) = g.find("E") cost = 0 sd = dict() de = dict() queue = deque([(start[0], start[1], 0)]) seen = set() while queue: r, c, cost = queue.popleft() if (r, c) in sd: continue sd[(r, c)] = cost if (r, c) == end: break for r, c in g.neighbors_ort((r, c)): if g[(r, c)] != "#": queue.append((r, c, cost + 1)) seen = set() queue = deque([(end[0], end[1], 0)]) while queue: r, c, cost = queue.popleft() if (r, c) in de: continue de[(r, c)] = cost if (r, c) == start: break for r, c in g.neighbors_ort((r, c)): if g[(r, c)] != "#": queue.append((r, c, cost + 1)) for max_steps in [2, 20]: cheats = set() for cr, cc in g.find("S."): start = cr, cc, 0 seen = set() queue = deque([start]) while queue: r, c, steps = queue.popleft() if steps > max_steps: continue if (r, c) in seen: continue seen.add((r, c)) if g[(r, c)] != "#": ncost = sd[(cr, cc)] + steps + de[(r, c)] if cost - ncost >= 100: cheats.add((cr, cc, r, c)) for dr, dc in [(-1, 0), (0, 1), (1, 0), (0, -1)]: nr, nc = r + dr, c + dc if g.contains((nr, nc)): queue.append((nr, nc, steps + 1)) print(len(cheats))