63 lines
1.7 KiB
Python
63 lines
1.7 KiB
Python
|
import sys
|
||
|
from dataclasses import dataclass
|
||
|
from typing import Literal, cast
|
||
|
|
||
|
import parse # type: ignore
|
||
|
|
||
|
|
||
|
@dataclass(frozen=True)
|
||
|
class Reindeer:
|
||
|
name: str
|
||
|
speed: int
|
||
|
fly_time: int
|
||
|
rest_time: int
|
||
|
|
||
|
|
||
|
lines = sys.stdin.read().splitlines()
|
||
|
|
||
|
reindeers: list[Reindeer] = []
|
||
|
for line in lines:
|
||
|
reindeer, speed, speed_time, rest_time = cast(
|
||
|
tuple[str, int, int, int],
|
||
|
parse.parse( # type: ignore
|
||
|
"{} can fly {:d} km/s for {:d} seconds, "
|
||
|
"but then must rest for {:d} seconds.",
|
||
|
line,
|
||
|
),
|
||
|
)
|
||
|
reindeers.append(
|
||
|
Reindeer(name=reindeer, speed=speed, fly_time=speed_time, rest_time=rest_time)
|
||
|
)
|
||
|
|
||
|
target = 1000 if len(reindeers) <= 2 else 2503
|
||
|
|
||
|
states: dict[Reindeer, tuple[Literal["resting", "flying"], int]] = {
|
||
|
reindeer: ("resting", 0) for reindeer in reindeers
|
||
|
}
|
||
|
distances: dict[Reindeer, int] = {reindeer: 0 for reindeer in reindeers}
|
||
|
points: dict[Reindeer, int] = {reindeer: 0 for reindeer in reindeers}
|
||
|
|
||
|
for time in range(target):
|
||
|
for reindeer in reindeers:
|
||
|
if states[reindeer][0] == "flying":
|
||
|
distances[reindeer] += reindeer.speed
|
||
|
|
||
|
top_distance = max(distances.values())
|
||
|
for reindeer in reindeers:
|
||
|
if distances[reindeer] == top_distance:
|
||
|
points[reindeer] += 1
|
||
|
|
||
|
for reindeer in reindeers:
|
||
|
if states[reindeer][1] == time:
|
||
|
if states[reindeer][0] == "resting":
|
||
|
states[reindeer] = ("flying", time + reindeer.fly_time)
|
||
|
else:
|
||
|
states[reindeer] = ("resting", time + reindeer.rest_time)
|
||
|
|
||
|
|
||
|
answer_1 = max(distances.values())
|
||
|
print(f"answer 1 is {answer_1}")
|
||
|
|
||
|
answer_2 = max(points.values()) - 1
|
||
|
print(f"answer 2 is {answer_2}")
|