diff --git a/2024-python/output/day_16.py b/2024-python/output/day_16.py index 781c902..048bfac 100644 --- a/2024-python/output/day_16.py +++ b/2024-python/output/day_16.py @@ -1,85 +1,78 @@ -import re -from collections import Counter, defaultdict, deque from heapq import heappop, heappush -from itertools import chain, combinations, compress, permutations -from output import ADJ, DD, D, ccw, cw, ints, matrix, mdbg, mhd, vdbg +from output import D, matrix def solve(data): grid, H, W = matrix(data) S = [(r, c) for r in range(H) for c in range(W) if grid[r][c] == "S"][0] E = [(r, c) for r in range(H) for c in range(W) if grid[r][c] == "E"][0] - p1 = float('inf') - Q = deque([(0, (S,), 1)]) + Q = [(0, S, 1)] + p1 = float("inf") + SE = dict() + ES = dict() seen = set() - lowest = [] while Q: - cost, path, facing = heappop(Q) - pos = path[-1] - if (pos, facing) in seen: - continue - seen.add((pos, facing)) - if pos == E: - p1 = min(cost, p1) - lowest.append(path) + cost, pos, dir = heappop(Q) r, c = pos - for d, delta in enumerate(D): + if grid[r][c] == "#": + continue + if (r, c, dir) in seen: + continue + seen.add((r, c, dir)) + if (r, c, dir) not in SE: + SE[(r, c, dir)] = cost + if pos == E: + p1 = min(p1, cost) + continue + for inc, delta, facing in [ + (1, D[dir], dir), + (1000, (0, 0), (dir + 1) % 4), + (1000, (0, 0), (dir - 1) % 4), + ]: + nc = cost + inc dr, dc = delta - if grid[r + dr][c + dc] == "#": - continue - if abs(facing - d) == 2: - continue - if d != facing: - heappush(Q, (cost + 1000, path, d)) - else: - heappush(Q, (cost + 1, path + ((r + dr, c + dc),), d)) - return p1, None + heappush(Q, (nc, (r + dr, c + dc), facing)) + Q = [(0, E, 0), (0, E, 1), (0, E, 2), (0, E, 3)] + seen = set() + while Q: + cost, pos, dir = heappop(Q) + r, c = pos + if grid[r][c] == "#": + continue + if (r, c, dir) in seen: + continue + seen.add((r, c, dir)) + if (r, c, (dir + 2) % 4) not in ES: + ES[(r, c, (dir + 2) % 4)] = cost + if pos == S: + continue + for inc, delta, facing in [ + (1, D[dir], dir), + (1000, (0, 0), (dir + 1) % 4), + (1000, (0, 0), (dir - 1) % 4), + ]: + nc = cost + inc + dr, dc = delta + heappush(Q, (nc, (r + dr, c + dc), facing)) + p2 = set() + for r in range(H): + for c in range(W): + for d in range(4): + if ( + (r, c, d) in SE + and (r, c, d) in ES + and SE[(r, c, d)] + ES[(r, c, d)] == p1 + ): + p2.add((r, c)) + return p1, len(p2) if __name__ == "__main__": - import os - - # use dummy data - inp = """ - ################# - #...#...#...#..E# - #.#.#.#.#.#.#.#.# - #.#.#.#...#...#.# - #.#.#.#.###.#.#.# - #...#.#.#.....#.# - #.#.#.#.#.#####.# - #.#...#.#.#.....# - #.#.#####.#.###.# - #.#.#.......#...# - #.#.###.#####.### - #.#.#...#.....#.# - #.#.#.#####.###.# - #.#.#.........#.# - #.#.#.#########.# - #S#.............# - ################# - - - - """.strip() - - # uncomment to instead use stdin - # import sys; inp = sys.stdin.read().strip() - - # uncomment to use AoC provided puzzle input with open("./input/16.txt", "r") as f: inp = f.read().strip() - # uncomment to do initial data processing shared by part 1-2 p1, p2 = solve(inp) print(p1) - os.system(f"echo {p1} | wl-copy") print(p2) - os.system(f"echo {p2} | wl-copy") - - # uncomment and replace 0 with actual output to refactor code - # and ensure nonbreaking changes - # assert p1 == 0 - # assert p2 == 0