from utils import open_day from dataclasses import dataclass @dataclass class Cell: num: int marked: bool = False Board = list[list[Cell]] def bingo(board: Board) -> bool: for row in board: if all(cell.marked for cell in row): return True for x in range(len(board[0])): if all(board[y][x].marked for y in range(len(board))): return True return False def solve(nums: list[int], boards: list[Board]) -> tuple[int, int]: won: set[int] = set() wins: list[int] = [] num: int for num in nums: i: int board: Board for i, board in enumerate(boards): total = 0 for row in board: for cell in row: if cell.num == num: cell.marked = True if not cell.marked: total += cell.num if i not in won and bingo(board): won.add(i) wins.append(num * total) return wins[0], wins[-1] nums: str | list[int] boards: list[str] | list[Board] nums, *boards = open_day(4).read().rstrip().split('\n\n') nums = list(map(int, nums.split(','))) boards = [[[Cell(int(n)) for n in l.split()] for l in b.split('\n')] for b in boards] part1, part2 = solve(nums, boards) print(part1) print(part2)