kupuguy

Advent of Code 2024 Day 13

Dec 14th, 2024
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.05 KB | Source Code | 0 0
  1. from pathlib import Path
  2. import re
  3. from typing import Sequence
  4.  
  5.  
  6. TEST = """**redacted**"""
  7.  
  8.  
  9. def parse(
  10.     input: str,
  11. ) -> Sequence[tuple[tuple[int, int], tuple[int, int], tuple[int, int]]]:
  12.     values = [int(n) for n in re.findall(r"\d+", input, re.MULTILINE)]
  13.     while values:
  14.         yield (values[0], values[1]), (values[2], values[3]), (values[4], values[5])
  15.         del values[:6]
  16.  
  17.  
  18. def solve(a: tuple[int, int], b: tuple[int, int], prize: [int, int]) -> int:
  19.     a_x, a_y = a
  20.     b_x, b_y = b
  21.     prize_x, prize_y = prize
  22.     cost = 999
  23.     for b_press in range(1, 101):
  24.         res_x = prize_x - (b_press * b_x)
  25.         res_y = prize_y - (b_press * b_y)
  26.         if res_x < 0 or res_y < 0:
  27.             break
  28.         if res_x % a_x == 0:
  29.             press_a = res_x // a_x
  30.             if a_y * press_a == res_y:
  31.                 cost = min(3 * press_a + b_press, cost)
  32.     return 0 if cost == 999 else cost
  33.  
  34.  
  35. def part1(input: str) -> int:
  36.     return sum(solve(a, b, prize) for a, b, prize in parse(input))
  37.  
  38.  
  39. assert part1(TEST) == 480
  40.  
  41. INPUT = Path("input/day13.txt").read_text()
  42. part1_total = part1(INPUT)
  43. print(f"{part1_total=:,}")  # 34,393
  44.  
  45. ERROR = 10_000_000_000_000
  46.  
  47.  
  48. def solve_2(
  49.     a: tuple[int, int], b: tuple[int, int], prize: [int, int], error: int
  50. ) -> int:
  51.     a_x, a_y = a
  52.     b_x, b_y = b
  53.     prize_x, prize_y = prize[0] + error, prize[1] + error
  54.  
  55.     num = a_x * b_x * prize_y - a_y * b_x * prize_x
  56.     denom = a_x * b_y - a_y * b_x
  57.     x_intersect = num // denom
  58.     press_b = x_intersect // b_x
  59.     press_a = (prize_x - x_intersect) // a_x
  60.     if (
  61.         press_a >= 0
  62.         and press_b >= 0
  63.         and a_y * press_a + b_y * press_b == prize_y
  64.         and a_x * press_a + b_x * press_b == prize_x
  65.     ):
  66.         return press_b + 3 * press_a
  67.     return 0
  68.  
  69.  
  70. def part2(input: str, error: int = ERROR) -> int:
  71.     return sum(solve_2(a, b, prize, error=error) for a, b, prize in parse(input))
  72.  
  73.  
  74. print(f"Part 1: {part2(INPUT, error=0):,}") # 34,393
  75. print(f"Part 2: {part2(INPUT):,}")  # 83,551,068,361,379
Advertisement
Add Comment
Please, Sign In to add comment