78 lines
2.3 KiB
Python
78 lines
2.3 KiB
Python
from aoc import AOCDay
|
|
from typing import Any
|
|
|
|
|
|
class BingoCard:
|
|
def __init__(self, numbers: str):
|
|
numbers = list(map(int, numbers.strip().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()
|