aoc2023/day02.py

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()