Files
aocpy/2024/d21.py

88 lines
2.2 KiB
Python

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)