from aoc import AOCDay from typing import Any class BingoCard: def __init__(self, numbers: str): numbers = list(map(int, numbers.strip().replace(" ", " ").split(" "))) self.fields = {} self.checked = {} for y in range(5): for x in range(5): self.fields[(x, y)] = numbers[y * 5 + x] self.checked[(x, y)] = False def getScore(self, number: int) -> int: unmarked_score = 0 for x1 in range(5): for y1 in range(5): if not self.checked[(x1, y1)]: unmarked_score += self.fields[(x1, y1)] return unmarked_score * number def checkNumber(self, number: int) -> bool: if number not in self.fields.values(): return False for x in range(5): for y in range(5): if self.fields[(x, y)] == number: self.checked[(x, y)] = True for x in range(5): found_x = 0 found_y = 0 for y in range(5): if self.checked[(x, y)]: found_y += 1 if self.checked[(y, x)]: found_x += 1 if found_x == 5 or found_y == 5: return True return False class Day(AOCDay): test_solutions_p1 = [4512] test_solutions_p2 = [1924] def part1(self) -> Any: numbers_and_boards = self.getMultiLineInputAsArray(join_char=" ") numbers_drawn = list(map(int, numbers_and_boards[0].split(","))) cards = [BingoCard(cl) for cl in numbers_and_boards[1:]] for number in numbers_drawn: for i, card in enumerate(cards): if card.checkNumber(number): return card.getScore(number) def part2(self) -> Any: numbers_and_boards = self.getMultiLineInputAsArray(join_char=" ") numbers_drawn = list(map(int, numbers_and_boards[0].split(","))) cards = [BingoCard(cl) for cl in numbers_and_boards[1:]] for number in numbers_drawn: remaining_cards = cards.copy() for i, card in enumerate(cards): if card.checkNumber(number): if len(remaining_cards) == 1: return remaining_cards[0].getScore(number) remaining_cards.remove(card) cards = remaining_cards.copy()