aoc24/day13/solution.py
2024-12-13 11:04:25 +01:00

78 lines
No EOL
2.3 KiB
Python

from argparse import ArgumentParser
def parse_line(line: str) -> tuple[int, int]:
line = line.strip()
parts = line.split(':', 1)
coords_part = parts[1].strip()
x_part, y_part = coords_part.split(',')
x_val = x_part.strip()[1:]
y_val = y_part.strip()[1:]
return int(x_val), int(y_val)
def is_solvable(XA, YA, XB, YB, Xp, Yp, max_presses=100):
best_cost = None
for a in range(max_presses+1):
for b in range(max_presses+1):
X = XA * a + XB * b
Y = YA * a + YB * b
if X == Xp and Y == Yp:
cost = 3*a + b
if best_cost is None or cost < best_cost:
best_cost = cost
return best_cost
def format_buttons(a: str, b: str, prize: str) -> dict:
XA, YA = parse_line(a)
XB, YB = parse_line(b)
_, p_coords = prize.split(':', 1)
p_coords = p_coords.strip()
# p_coords = "X=8400, Y=5400"
x_part, y_part = p_coords.split(',')
Xp = int(x_part.strip()[2:])
Yp = int(y_part.strip()[2:])
return {
"A": {"X": XA, "Y": YA},
"B": {"X": XB, "Y": YB},
"PRIZE": {"X": Xp, "Y": Yp}
}
def main(machines: list[list[str]]) -> int:
results = []
for part in machines:
button_a = part[0]
button_b = part[1]
prize = part[2]
formatted = format_buttons(button_a, button_b, prize)
XA, YA = formatted["A"]["X"], formatted["A"]["Y"]
XB, YB = formatted["B"]["X"], formatted["B"]["Y"]
Xp, Yp = formatted["PRIZE"]["X"], formatted["PRIZE"]["Y"]
cost = is_solvable(XA, YA, XB, YB, Xp, Yp, max_presses=100)
if cost is not None:
results.append(cost)
if not results:
return 0
return sum(results)
def parse_input(input_file) -> list[list[str]]:
with open(input_file, "r") as f:
content = f.read().strip()
machine_blocks = content.split("\n\n")
machines = []
for block in machine_blocks:
lines = block.strip().splitlines()
if len(lines) == 3:
machines.append(lines)
return machines
if __name__ == "__main__":
parser = ArgumentParser(description="Solve claw machine problem")
parser.add_argument("-f", "--file", required=True, help="Input file")
args = parser.parse_args()
input_data = parse_input(args.file)
print(main(input_data))