advent-of-code/src/holt59/aoc/2023/day6.py
Mikaël Capelle ce315b8778 Refactor code for API (#3)
Co-authored-by: Mikael CAPELLE <mikael.capelle@thalesaleniaspace.com>
Co-authored-by: Mikaël Capelle <capelle.mikael@gmail.com>
Reviewed-on: #3
2024-12-08 13:06:41 +00:00

50 lines
1.3 KiB
Python

import math
from typing import Any, Iterator
from ..base import BaseSolver
def extreme_times_to_beat(time: int, distance: int) -> tuple[int, int]:
# formula (T = total time, D = target distance)
# - speed(t) = t,
# - distance(t) = (T - t) * speed(t)
# - distance(t) > D
# <=> (T - t) * t > D
# <=> -t^2 + T * t - D >= 0
a, b, c = -1, time, -distance
d = b * b - 4 * a * c
t1 = math.ceil(-(b - math.sqrt(d)) / (2 * a))
t2 = math.floor(-(b + math.sqrt(d)) / (2 * a))
if (time - t1) * t1 == distance:
t1 += 1
if (time - t2) * t2 == distance:
t2 -= 1
return t1, t2
class Solver(BaseSolver):
def solve(self, input: str) -> Iterator[Any]:
lines = input.splitlines()
# part 1
times = list(map(int, lines[0].split()[1:]))
distances = list(map(int, lines[1].split()[1:]))
yield math.prod(
t2 - t1 + 1
for t1, t2 in (
extreme_times_to_beat(time, distance)
for time, distance in zip(times, distances)
)
)
# part 2
time = int(lines[0].split(":")[1].strip().replace(" ", ""))
distance = int(lines[1].split(":")[1].strip().replace(" ", ""))
t1, t2 = extreme_times_to_beat(time, distance)
yield t2 - t1 + 1