aoc2024/day13.py

73 lines
2.3 KiB
Python

from math import lcm
from tools.aoc import AOCDay
from typing import Any
BLOWUP_FACTOR = 10_000_000_000_000
def solve(machine: tuple[tuple[int, int], tuple[int, int], tuple[int, int]], part2: bool = False) -> tuple[int, int]:
# ax + by = c # for machine[a][0] and machine[b][0]; and again for machine[x][1]
# y = (c - ax) / b
# And yes, I know I could have just used sympy or numpy, but I wanted to learn something; and this is fast enough
lcm_a = lcm(machine[0][0], machine[0][1])
tmb_one = lcm_a / machine[0][0]
tmb_two = lcm_a / machine[0][1]
a1 = machine[0][0] * tmb_one
b1 = machine[1][0] * tmb_one
b2 = machine[1][1] * tmb_two
if not part2:
c1 = machine[2][0] * tmb_one
c2 = machine[2][1] * tmb_two
else:
c1 = (machine[2][0] + BLOWUP_FACTOR) * tmb_one
c2 = (machine[2][1] + BLOWUP_FACTOR) * tmb_two
y = (c1 - c2) / (b1 - b2)
x = (c1 - (b1 * y)) / a1
if x == int(x) and y == int(y):
return int(x), int(y)
else:
return -1, -1
class Day(AOCDay):
inputs = [
[
(480, "input13_test"),
(29438, "input13_dennis"),
(33427, "input13"),
],
[
(104958599303720, "input13_dennis"),
(91649162972270, "input13"),
],
]
def parse_input(self) -> list[tuple[tuple[int, int], tuple[int, int], tuple[int, int]]]:
machines = []
for machine in self.getMultiLineInputAsArray():
button_a = machine[0].split(": ")[1]
button_a_x, button_a_y = (int(x[2:]) for x in button_a.split(", "))
button_b = machine[1].split(": ")[1]
button_b_x, button_b_y = (int(x[2:]) for x in button_b.split(", "))
prize = machine[2].split(": ")[1]
prize_x, prize_y = (int(x[2:]) for x in prize.split(", "))
machines.append(((button_a_x, button_a_y), (button_b_x, button_b_y), (prize_x, prize_y)))
return machines
def part1(self) -> Any:
solves = [solve(machine) for machine in self.parse_input()]
return sum(3 * x + y for x, y in solves if x > 0)
def part2(self) -> Any:
solves = [solve(machine, part2=True) for machine in self.parse_input()]
return sum(3 * x + y for x, y in solves if x > 0)
if __name__ == "__main__":
day = Day(2024, 13)
day.run(verbose=True)