aoc2021/day04.py

91 lines
2.5 KiB
Python

from tools.aoc import AOCDay
from typing import Any
class BingoCard:
def __init__(self, numbers: str):
numbers = list(map(int, numbers.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):
inputs = [
[
(4512, "test_input04"),
(58374, "input04")
],
[
(1924, "test_input04"),
(11377, "input04")
]
]
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()
if __name__ == '__main__':
day = Day(4)
day.run(verbose=True)