from __future__ import annotations from dataclasses import dataclass from collections import deque from aoc import Aoc @dataclass class Card: card_id: int wins: int winning: list[int] have: list[int] @staticmethod def from_line(line: str) -> Card: id_section, number_section = line.split(": ") _, card_id = [s for s in id_section.split(" ") if s.strip()] winning_str, have_str = number_section.split(" | ") winning = [int(nr.strip()) for nr in winning_str.split(" ") if nr.strip()] have = [int(nr.strip()) for nr in have_str.split(" ") if nr.strip()] wins = len(set(winning).intersection(have)) return Card(int(card_id),wins, winning, have) class Day04(Aoc[list[Card]]): def __init__(self) -> None: super().__init__(2023, 4) def parseinput(self, inpt: str) -> list[Card]: lines = inpt.splitlines() return [Card.from_line(line) for line in lines] 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: stack = deque(range(len(cards))) complete = len(cards) while stack: card_id = stack.popleft() for win in range(cards[card_id].wins): stack.appendleft(win + card_id + 1) complete += 1 return complete def main() -> None: day4 = Day04() day4.run() if __name__ == "__main__": main()