aoc2023/day04.py

56 lines
1.4 KiB
Python

from __future__ import annotations
from dataclasses import dataclass
import regex
from aoc import Aoc2, AocParseLinesSameParser
@dataclass
class Card:
card_id: int
wins: int
win: list[int]
have: list[int]
@staticmethod
def from_line(line: str) -> Card:
matches = regex.match(
r"Card\s*(?P<card_id>\d+):(\s*(?P<win>\d+)\s*)*\|(\s*(?P<have>\d+)\s*)*",
line,
)
if matches is None:
raise RuntimeError(f'Could not parse "{line}"')
win = [int(d) for d in matches.captures("win")]
have = [int(d) for d in matches.captures("have")]
wins = len(set(win).intersection(have))
return Card(int(matches["card_id"]), wins, win, have)
class Day04(AocParseLinesSameParser[Card], Aoc2[list[Card], list[Card]]):
def __init__(self) -> None:
Aoc2.__init__(self, 2023, 4)
def parseline(self, inpt: str) -> Card:
return Card.from_line(inpt)
def part1(self, cards: list[Card]) -> int:
return sum(2 ** (card.wins - 1) for card in cards if card.wins)
def part2(self, cards: list[Card]) -> int:
d = [0] * len(cards)
for card in reversed(cards):
d[card.card_id - 1] = 1 + sum(
d[card.card_id + i] for i in range(card.wins)
)
return sum(d)
def main() -> None:
day4 = Day04()
day4.run()
if __name__ == "__main__":
main()