63 lines
1.3 KiB
Python
63 lines
1.3 KiB
Python
|
import operator
|
||
|
import sys
|
||
|
from dataclasses import dataclass
|
||
|
from functools import reduce
|
||
|
from typing import Literal, TypeAlias, cast
|
||
|
|
||
|
Cube: TypeAlias = Literal["red", "blue", "green"]
|
||
|
|
||
|
|
||
|
@dataclass(frozen=True)
|
||
|
class Game:
|
||
|
id: int
|
||
|
set_of_cubes: list[dict[Cube, int]]
|
||
|
|
||
|
|
||
|
lines = sys.stdin.read().split("\n")
|
||
|
|
||
|
games: list[Game] = []
|
||
|
for line in filter(bool, lines):
|
||
|
id_part, sets_part = line.split(":")
|
||
|
|
||
|
games.append(
|
||
|
Game(
|
||
|
id=int(id_part.split(" ")[-1]),
|
||
|
set_of_cubes=[
|
||
|
{
|
||
|
cast(Cube, s[1]): int(s[0])
|
||
|
for cube_draw in cube_set_s.strip().split(", ")
|
||
|
if (s := cube_draw.split(" "))
|
||
|
}
|
||
|
for cube_set_s in sets_part.strip().split(";")
|
||
|
],
|
||
|
)
|
||
|
)
|
||
|
|
||
|
# part 1
|
||
|
MAX_CUBES: dict[Cube, int] = {"red": 12, "green": 13, "blue": 14}
|
||
|
|
||
|
answer_1 = sum(
|
||
|
game.id
|
||
|
for game in games
|
||
|
if all(
|
||
|
n_cubes <= MAX_CUBES[cube]
|
||
|
for cube_set in game.set_of_cubes
|
||
|
for cube, n_cubes in cube_set.items()
|
||
|
)
|
||
|
)
|
||
|
|
||
|
print(f"answer 1 is {answer_1}")
|
||
|
|
||
|
# part 2
|
||
|
answer_2 = sum(
|
||
|
reduce(
|
||
|
operator.mul,
|
||
|
(
|
||
|
max(cube_set.get(cube, 0) for cube_set in game.set_of_cubes)
|
||
|
for cube in MAX_CUBES
|
||
|
),
|
||
|
)
|
||
|
for game in games
|
||
|
)
|
||
|
print(f"answer 2 is {answer_2}")
|