88 lines
2.2 KiB
Python
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)
|