80 lines
1.9 KiB
Python
80 lines
1.9 KiB
Python
from __future__ import annotations
|
|
from dataclasses import dataclass
|
|
|
|
from .aoc import Aoc2, AocParseLinesSameParser
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class GameSet:
|
|
red: int
|
|
green: int
|
|
blue: int
|
|
|
|
@staticmethod
|
|
def from_line(line: str) -> GameSet:
|
|
cubes = line.split(", ")
|
|
gather_dict = {}
|
|
for cube_str in cubes:
|
|
amount, color = cube_str.split(" ")
|
|
gather_dict[color] = int(amount)
|
|
return GameSet(
|
|
gather_dict.get("red", 0),
|
|
gather_dict.get("green", 0),
|
|
gather_dict.get("blue", 0),
|
|
)
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class Game:
|
|
game_id: int
|
|
sets: list[GameSet]
|
|
|
|
def power(self) -> int:
|
|
return self.maxblue * self.maxred * self.maxgreen
|
|
|
|
@property
|
|
def maxblue(self) -> int:
|
|
return max(s.blue for s in self.sets)
|
|
|
|
@property
|
|
def maxred(self) -> int:
|
|
return max(s.red for s in self.sets)
|
|
|
|
@property
|
|
def maxgreen(self) -> int:
|
|
return max(s.green for s in self.sets)
|
|
|
|
@property
|
|
def valid(self) -> bool:
|
|
return self.maxred <= 12 and self.maxgreen <= 13 and self.maxblue <= 14
|
|
|
|
@staticmethod
|
|
def from_line(line: str) -> Game:
|
|
game_str, sets_str = line.split(": ")
|
|
_, gameid = game_str.split(" ")
|
|
set_str_list = sets_str.split("; ")
|
|
|
|
return Game(int(gameid), [GameSet.from_line(s) for s in set_str_list])
|
|
|
|
|
|
class Day02(AocParseLinesSameParser[Game], Aoc2[list[Game], list[Game]]):
|
|
def __init__(self) -> None:
|
|
Aoc2.__init__(self, 2023, 2)
|
|
|
|
def parseline(self, inpt: str) -> Game:
|
|
return Game.from_line(inpt)
|
|
|
|
def part1(self, games: list[Game]) -> int:
|
|
return sum(game.game_id for game in games if game.valid)
|
|
|
|
def part2(self, games: list[Game]) -> int:
|
|
return sum(g.power() for g in games)
|
|
|
|
|
|
def main() -> None:
|
|
day2_aoc = Day02()
|
|
day2_aoc.run()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|