advent-of-code/2021/python/day04.py

95 lines
2.6 KiB
Python

import shared
from itertools import groupby
from pprint import pprint as pp
from matrix import rotate, load_matrix_file, split_line_to_int_list, get_column
from copy import deepcopy
def all_equal(iterable):
g = groupby(iterable)
return next(g, True) and not next(g, False)
class Bingo:
def __init__(self, name):
self.parse(name)
def parse(self, name):
with open(name, "r") as f:
lines = [x.rstrip() for x in f.readlines()]
self.rolls = [int(x) for x in lines.pop(0).split(",")]
lines.pop(0)
self.boards = []
current_board = []
while len(lines) > 0:
line = lines.pop(0)
if line == "":
self.boards.append(current_board)
current_board = []
continue
current_board.append(split_line_to_int_list(line))
if len(lines) == 0:
self.boards.append(current_board)
self.board_snapshot = deepcopy(self.boards)
def mark_roll(self, roll):
for idB, b in enumerate(self.boards):
breaking = False
for x, row in enumerate(b):
for y, col in enumerate(row):
if col == roll:
self.boards[idB][x][y] = -1
breaking = True
break
if breaking:
break
for idB, b in enumerate(self.boards):
winning_board = self.check_remove(idB)
if winning_board:
return winning_board
def check_remove(self, board_idx):
for row in self.boards[board_idx]:
if all_equal(row):
b = self.boards.pop(board_idx)
if len(self.boards) == 0:
return b
return
for col in zip(*self.boards[board_idx]):
if all_equal(col):
b = self.boards.pop(board_idx)
if len(self.boards) == 0:
return b
return
def roll(self):
roll = self.rolls.pop(0)
self.last_roll = roll
return self.mark_roll(roll)
def roll_all(self):
while len(self.rolls):
bingoCheck = self.roll()
if bingoCheck:
self.winner = bingoCheck
return
def total(self):
total = 0
for row in self.winner:
for col in row:
if col != -1:
total += col
return total * self.last_roll
def main():
b = Bingo(shared.get_fname(4))
b.roll_all()
print(b.total())
if __name__ == "__main__":
main()