71 lines
1.9 KiB
Python
71 lines
1.9 KiB
Python
#!/usr/bin/env python
|
|
# -*- encoding: utf-8; py-indent-offset: 4 -*-
|
|
|
|
# Author: Sebastian Mark
|
|
# CC-BY-SA (https://creativecommons.org/licenses/by-sa/4.0/deed.de)
|
|
|
|
# pylint: disable=missing-module-docstring,missing-function-docstring,consider-using-f-string
|
|
|
|
# algorithm stolen from:
|
|
# https://www.reddit.com/r/adventofcode/comments/1hd7irq/2024_day_13_an_explanation_of_the_mathematics/
|
|
|
|
import re
|
|
|
|
|
|
def readinput():
|
|
with open("input", "r", encoding="utf-8") as file:
|
|
lines = file.read()
|
|
entries = lines.strip().split("\n\n")
|
|
|
|
games = []
|
|
for entry in entries:
|
|
regex = r"Button A: X(.*), Y+(.*)\nButton B: X+(.*), Y+(.*)\nPrize: X=(.*), Y=(.*)"
|
|
match = re.match(regex, "".join(entry))
|
|
games.append(
|
|
{
|
|
"A": (int(match.group(1)), int(match.group(2))),
|
|
"B": (int(match.group(3)), int(match.group(4))),
|
|
"Prize": (int(match.group(5)), int(match.group(6))),
|
|
}
|
|
)
|
|
|
|
return games
|
|
|
|
|
|
def min_tokens_for_game(game) -> int:
|
|
# pylint: disable=invalid-name
|
|
AX, AY = game["A"]
|
|
BX, BY = game["B"]
|
|
PrizeX, PrizeY = game["Prize"]
|
|
|
|
PressA = (PrizeX * BY - PrizeY * BX) / (AX * BY - AY * BX)
|
|
PressB = (PrizeY * AX - PrizeX * AY) / (AX * BY - AY * BX)
|
|
|
|
if not (PressA == int(PressA) and PressB == int(PressB)):
|
|
return 0
|
|
|
|
return (PressA * 3) + PressB
|
|
|
|
|
|
def main():
|
|
games = readinput()
|
|
|
|
# part 1
|
|
tokens = 0
|
|
for game in games:
|
|
tokens += min_tokens_for_game(game)
|
|
print("Tokens required (Part 1): %d" % tokens)
|
|
|
|
# part 2
|
|
tokens = 0
|
|
for game in games:
|
|
game["Prize"] = (
|
|
game["Prize"][0] + 10000000000000,
|
|
game["Prize"][1] + 10000000000000,
|
|
)
|
|
tokens += min_tokens_for_game(game)
|
|
print("Tokens required (Part 2): %d" % tokens)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|