import re from collections import deque, Counter, defaultdict from heapq import heappop, heappush from itertools import compress, combinations, chain, permutations from functools import cache from output import matrix, D, DD, DDa, ADJ, ints, mhd, mdbg, vdbg, cw, ccw DKP = { "^": (0, 1), "A": (0, 2), "<": (1, 0), "v": (1, 1), ">": (1, 2), } NKP = { "7": (0, 0), "8": (0, 1), "9": (0, 2), "4": (1, 0), "5": (1, 1), "6": (1, 2), "1": (2, 0), "2": (2, 1), "3": (2, 2), "0": (3, 1), "A": (3, 2), } def solve(data): codes = data.split() p1 = 0 for code in codes: seqlen = unwrap(code) num = int(code[:-1]) p1 += num * seqlen p2 = None return p1, p2 def unwrap(dests): seqlen = float("inf") for num_path in press(dests, NKP): for d0_path in press(num_path, DKP): for d1_path in press(d0_path, DKP): seqlen = min(seqlen, len(d1_path)) return seqlen def press(dests, pad): s = "A" P = [""] for d in dests: paths = bfs(tuple(pad.values()), pad[s], pad[d]) ml = len(sorted(paths, key=lambda x: len(x))[0]) sp = [p for p in paths if len(p) == ml] nP = [] for a in P: for b in sp: nP.append(a + b) P = nP s = d P = sorted(P, key=lambda x: len(x)) psl = len(P[0]) return [p for p in P if len(p) == psl] @cache def bfs(grid, S, E): seen = set() Q = deque([(S, "<", "")]) paths = [] while Q: pos, dn, path = Q.popleft() if (pos, dn) in seen: continue if pos == E: paths.append(path + "A") continue seen.add((pos, dn)) y, x = pos for dn, delta in DDa.items(): dy, dx = delta if (y + dy, x + dx) in grid: Q.append(((y + dy, x + dx), dn, path + dn)) return paths if __name__ == "__main__": import os # use dummy data inp = """ 029A 980A 179A 456A 379A """.strip() """ 68 * 29 60 * 980 68 * 179 64 * 456 64 * 379 """ # uncomment to instead use stdin # import sys; inp = sys.stdin.read().strip() # uncomment to use AoC provided puzzle input with open("./input/21.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