advent_of_code/2021/4/4_2.py

117 lines
3.1 KiB
Python
Raw Permalink Normal View History

2021-12-07 00:25:43 +01:00
#!/usr/bin/env python
# 2021 - Advent Of Code - 4 part 2
import re
re_parse = re.compile(r'\s?(\d+)\s+'*4 + r'(\d+)')
GRID_SIZE = 5
class Board:
def __init__(self, grid):
self.grid = grid
self.marked = [[0] * GRID_SIZE for _ in range(GRID_SIZE)]
def print_with_mark(self):
for x in range(GRID_SIZE):
print(f'{self.grid[x]} \t {self.marked[x]}')
def mark_number(self, num):
for line in range(GRID_SIZE):
try:
index = self.grid[line].index(num)
self.marked[line][index] = 1
if self.has_win():
return True
return False
except ValueError:
pass
return False
def has_win(self):
# check lines
for line in range(GRID_SIZE):
if 0 not in self.marked[line]:
return True
# check column
for c in range(GRID_SIZE):
col_sum = 0
for line in range(GRID_SIZE):
if self.marked[line][c] == 0:
break
2021-12-12 17:23:29 +01:00
col_sum += 1
2021-12-07 00:25:43 +01:00
if col_sum == GRID_SIZE:
return True
return False
def calc_unmarked(self):
unmarked_sum = 0
for line in range(GRID_SIZE):
for col in range(GRID_SIZE):
if self.marked[line][col] == 0:
unmarked_sum += int(self.grid[line][col])
return unmarked_sum
def parse_file(file):
boards_list = []
2022-04-05 13:27:24 +02:00
with open(file, encoding="utf-8") as f:
2021-12-07 00:25:43 +01:00
numbers = f.readline().split(',')
line = f.readline()
while line:
board = []
2021-12-12 17:23:29 +01:00
for _ in range(GRID_SIZE):
2021-12-07 00:25:43 +01:00
line = f.readline()
m = re_parse.match(line)
grid_line = m.groups()
board.append(grid_line)
b = Board(board)
boards_list.append(b)
line = f.readline()
return boards_list, numbers
def play(boards_list, draws):
""" call all numbers
could stop when all boards have won ;-) """
winners = []
for d in draws:
print(f'calling {d}')
winner = ()
round_winners = []
for board in boards_list:
if board.mark_number(d):
print("this board wins !")
board.print_with_mark()
winner = (board, d)
round_winners.append(winner)
if winner:
print(f'round winners: {len(round_winners)}')
for r in round_winners:
boards_list.remove(r[0])
winners.extend(round_winners)
print(f'number of winners: {len(winners)}')
return winners
2021-12-12 17:23:29 +01:00
boards, calls = parse_file('input.txt')
2021-12-07 00:25:43 +01:00
print(f'number of boards: {len(boards)}')
# (winning_board, last_num) = play_until_win(boards, draws)
2021-12-12 17:23:29 +01:00
winning_boards = play(boards, calls)
2021-12-07 00:25:43 +01:00
winning_board, last_num = winning_boards[-1]
print(f'last number is: {last_num}')
board_score = winning_board.calc_unmarked()
print(f'board score: {board_score}')
score = int(last_num) * board_score
print(f'score is : {score}')