# pyright: strict from dataclasses import dataclass from functools import cache from sys import stdin from typing import Type @dataclass(frozen=True) class Card: id: int winning: frozenset[int] have: frozenset[int] @property def nmatching(self) -> int: return len(self.winning & self.have) @classmethod def from_str[T](cls: Type[T], s: str) -> T: card, rest = s.split(": ") _, card_id = card.split() winning, have = rest.split(" | ") return cls( int(card_id), frozenset(map(int, winning.split())), frozenset(map(int, have.split())), ) cards = [Card.from_str(l.rstrip()) for l in stdin] cards = {c.id: c for c in cards} @cache def p2_impl(card: Card) -> int: return 1 + sum( p2_impl(cards[cid]) for cid in range(card.id + 1, card.id + card.nmatching + 1) ) print(sum(int(2 ** (c.nmatching - 1)) for c in cards.values())) print(sum(p2_impl(c) for c in cards.values()))