from lib import get_data from collections import deque from functools import cache data = get_data(__file__) # data = """029A # 980A # 179A # 456A # 379A""" def new_dir(current, move): return { "<": {">": "v"}, "^": {">": "A", "v": "v"}, "v": {"<": "<", ">": ">", "^": "^"}, ">": {"^": "A", "<": "v"}, "A": {"<": "^", "v": ">"}, }[current].get(move, None) def new_num(current, move): return { "7": {">": "8", "v": "4", }, "8": {"<": "7", ">": "9", "v": "5"}, "9": {"<": "8", "v": "6"}, "4": {"^": "7", ">": "5", "v": "1"}, "5": {"^": "8", ">": "6", "<": "4", "v": "2"}, "6": {"^": "9", "<": "5", "v": "3"}, "1": {"^": "4", ">": "2"}, "2": {"^": "5", ">": "3", "<": "1", "v": "0"}, "3": {"^": "6", "<": "2", "v": "A"}, "0": {"^": "2", ">": "A"}, "A": {"^": "3", "<": "0"}, }[current].get(move, None) @cache def find(code, depth, lookup): if depth == 0: return len(code) code = list(code) t = 0 current = "A" while code: solutions = [] target = code.pop(0) start = (current, "") seen = set() queue = deque([start]) while queue: node = queue.popleft() if node in seen: continue seen.add(node) if node[0] == target: solution = node[1] + "A" if len(solutions) == 0: solutions.append(solution) elif len(solutions[-1]) == len(solution): solutions.append(solution) else: break continue for c in "<>v^": next = lookup(node[0], c) if next is not None: queue.append((next, node[1] + c)) current = target t += min(find(code, depth - 1, new_dir) for code in solutions) return t p1, p2 = 0, 0 for line in data.splitlines(): i = int("".join([c for c in line if c.isdigit()])) s1 = find(line, 3, new_num) s2 = find(line, 26, new_num) p1 += s1 * i p2 += s2 * i print(p1) print(p2)