aoc-2023/d02/main.py

83 lines
1.9 KiB
Python

from pathlib import Path
from typing import TypedDict
class Grab(TypedDict):
red: int
blue: int
green: int
def grab_in_bag(bag: Grab, grab: Grab) -> bool:
for color, count in grab.items():
if count > bag[color]:
return False
return True
class Game:
def __init__(self, id: int, grabs: list[Grab] | None = None) -> None:
self.id = id
self.grabs = grabs if grabs else []
def possible(self, bag: Grab) -> bool:
return all(grab_in_bag(bag, grab) for grab in self.grabs)
def parse_line(line: str) -> Game:
line = line.strip()
game_parsed, _, grabs = line.partition(":")
id = int("".join(c for c in game_parsed if c.isnumeric()))
game = Game(id)
for grab_draw in grabs.split(";"):
grab = Grab(red=0, blue=0, green=0)
for color_draw in grab_draw.split(","):
color_draw = color_draw.strip()
count, _, color = color_draw.partition(" ")
grab[color] = int(count)
game.grabs.append(grab)
return game
def part1(input: Path) -> int:
bag = Grab(red=12, blue=14, green=13)
total = 0
with input.open() as f:
for line in f:
game = parse_line(line)
if game.possible(bag):
total += game.id
return total
def part2(input: Path) -> int:
total = 0
with input.open() as f:
for line in f:
bag = Grab(red=0, blue=0, green=0)
game = parse_line(line)
power = 1
for color in bag:
bag[color] = max(grab[color] for grab in game.grabs)
power *= bag[color]
# print(bag, power)
total += power
return total
if __name__ == "__main__":
answer1 = part1(Path("./input.txt"))
print("part 1", answer1)
answer2 = part2(Path("./input.txt"))
print("part 2", answer2)