This commit is contained in:
parent
30e0bb3665
commit
67e41503c9
15
poetry.lock
generated
15
poetry.lock
generated
@ -1,4 +1,4 @@
|
||||
# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand.
|
||||
# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand.
|
||||
|
||||
[[package]]
|
||||
name = "appnope"
|
||||
@ -353,6 +353,17 @@ files = [
|
||||
[package.dependencies]
|
||||
traitlets = "*"
|
||||
|
||||
[[package]]
|
||||
name = "more-itertools"
|
||||
version = "10.5.0"
|
||||
description = "More routines for operating on iterables, beyond itertools"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "more-itertools-10.5.0.tar.gz", hash = "sha256:5482bfef7849c25dc3c6dd53a6173ae4795da2a41a80faea6700d9f5846c5da6"},
|
||||
{file = "more_itertools-10.5.0-py3-none-any.whl", hash = "sha256:037b0d3203ce90cca8ab1defbbdac29d5f993fc20131f3664dc8d6acfa872aef"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mpmath"
|
||||
version = "1.3.0"
|
||||
@ -1295,4 +1306,4 @@ files = [
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.10"
|
||||
content-hash = "c91bc307ff4a5b3e8cd1976ebea211c9749fe09d563dd80861f70ce26826cda9"
|
||||
content-hash = "10ecc039b99b304e65eef14905c0fb0fcc7b8fb31328b19c65b54779fcc0e336"
|
||||
|
@ -16,6 +16,7 @@ scipy = "^1.14.1"
|
||||
sympy = "^1.13.3"
|
||||
networkx = "^3.4.2"
|
||||
pandas = "^2.2.3"
|
||||
more-itertools = "^10.5.0"
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
pyright = "^1.1.389"
|
||||
|
@ -1,7 +1,79 @@
|
||||
import math
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Iterator
|
||||
|
||||
import parse # pyright: ignore[reportMissingTypeStubs]
|
||||
|
||||
from ..base import BaseSolver
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class Machine:
|
||||
prize: tuple[int, int]
|
||||
button_a: tuple[int, int]
|
||||
button_b: tuple[int, int]
|
||||
|
||||
|
||||
def read_machine(block: str) -> Machine:
|
||||
ba = parse.parse( # type: ignore
|
||||
"""Button A: X{bax:d}, Y{bay:d}
|
||||
Button B: X{bbx:d}, Y{bby:d}
|
||||
Prize: X={px:d}, Y={py:d}""",
|
||||
block,
|
||||
)
|
||||
return Machine(
|
||||
prize=(ba["px"], ba["py"]), # type: ignore
|
||||
button_a=(ba["bax"], ba["bay"]), # type: ignore
|
||||
button_b=(ba["bbx"], ba["bby"]), # type: ignore
|
||||
)
|
||||
|
||||
|
||||
def diophantine(a: int, b: int, c: int) -> tuple[int, int]:
|
||||
q, r = divmod(a, b)
|
||||
if r == 0:
|
||||
return (0, c // b)
|
||||
else:
|
||||
u, v = diophantine(b, r, c)
|
||||
return (v, u - q * v)
|
||||
|
||||
|
||||
def solve(machine: Machine) -> int:
|
||||
(ax, ay), (bx, by), (px, py) = machine.button_a, machine.button_b, machine.prize
|
||||
dx, dy = math.gcd(ax, bx), math.gcd(ay, by)
|
||||
|
||||
if px % dx != 0 or py % dy != 0:
|
||||
return 0
|
||||
|
||||
xa, xb = diophantine(ax, bx, px)
|
||||
ya, yb = diophantine(ay, by, py)
|
||||
|
||||
# expr (x): xa - kx * bx / dx, xb + kx * ax / dx
|
||||
# expr (y): ya - ky * by / dy, yb + ky * ay / dy
|
||||
|
||||
num = ay * (ya - xa) + by * (yb - xb)
|
||||
den = (ax * by - ay * bx) // dx
|
||||
|
||||
if num % den != 0:
|
||||
return 0
|
||||
|
||||
kx = num // den
|
||||
pa, pb = xa - kx * bx // dx, xb + kx * ax // dx
|
||||
return 3 * pa + pb
|
||||
|
||||
|
||||
class Solver(BaseSolver):
|
||||
def solve(self, input: str) -> Iterator[Any]: ...
|
||||
def solve(self, input: str) -> Iterator[Any]:
|
||||
machines = [read_machine(block) for block in input.split("\n\n")]
|
||||
|
||||
yield sum(map(solve, machines))
|
||||
|
||||
shift = 10000000000000
|
||||
machines = [
|
||||
Machine(
|
||||
prize=(shift + m.prize[0], shift + m.prize[1]),
|
||||
button_a=m.button_a,
|
||||
button_b=m.button_b,
|
||||
)
|
||||
for m in machines
|
||||
]
|
||||
yield sum(map(solve, machines))
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,15 @@
|
||||
Button A: X+94, Y+34
|
||||
Button B: X+22, Y+67
|
||||
Prize: X=8400, Y=5400
|
||||
|
||||
Button A: X+26, Y+66
|
||||
Button B: X+67, Y+21
|
||||
Prize: X=12748, Y=12176
|
||||
|
||||
Button A: X+17, Y+86
|
||||
Button B: X+84, Y+37
|
||||
Prize: X=7870, Y=6450
|
||||
|
||||
Button A: X+69, Y+23
|
||||
Button B: X+27, Y+71
|
||||
Prize: X=18641, Y=10279
|
Loading…
Reference in New Issue
Block a user