advent-of-code/2024/13/one.py
2024-12-25 12:59:49 +01:00

79 lines
2 KiB
Python

#!/usr/bin/env python3
import functools
import re
import sys
input_file = sys.argv[1]
with open(input_file) as fd:
lines = [line.rstrip() for line in fd.readlines()]
coords = tuple[int, int]
prizes: list[coords] = list()
buttons: list[tuple[coords, coords]] = list()
for li, line in enumerate(lines):
machine = li // 4
offset = li % 4
if offset == 0:
match = re.match(r"^Button A: X\+([0-9]+), Y\+([0-9]+)$", line)
assert match
button_a = int(match[1]), int(match[2])
elif offset == 1:
match = re.match(r"^Button B: X\+([0-9]+), Y\+([0-9]+)$", line)
assert match
button_b = int(match[1]), int(match[2])
buttons.append((button_a, button_b))
elif offset == 2:
match = re.match("^Prize: X=([0-9]+), Y=([0-9]+)$", line)
assert match
prize = int(match[1]), int(match[2])
prizes.append(prize)
assert len(prizes) == len(buttons)
ttoks = 0
for arcade, prize in enumerate(prizes):
butts = buttons[arcade]
button_a, button_b = butts
@functools.lru_cache(4096)
def fun(x: int, y: int, rem_a: int, rem_b: int) -> int | None:
if (x, y) == prize:
return 0
if x > prize[0] or y > prize[1]:
return None
ba = (
fun(x + button_a[0], y + button_a[1], rem_a - 1, rem_b)
if rem_a > 0
else None
)
bb = (
fun(x + button_b[0], y + button_b[1], rem_a, rem_b - 1)
if rem_b > 0
else None
)
if ba is not None:
ba += 3
if bb is not None:
bb += 1
if ba is None:
if bb is None:
return None
else:
return bb
else:
if bb is None or ba < bb:
return ba
else:
return bb
toks = fun(0, 0, 100, 100)
print(43, arcade, toks)
if toks is not None:
ttoks += toks
# break
print(ttoks)