Day 4 part 2
This commit is contained in:
parent
dd8550e3b8
commit
0133915b71
1 changed files with 128 additions and 0 deletions
128
4/4_2.py
Executable file
128
4/4_2.py
Executable file
|
@ -0,0 +1,128 @@
|
|||
#!/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
|
||||
else:
|
||||
col_sum += 1
|
||||
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 = []
|
||||
with open(file) as f:
|
||||
numbers = f.readline().split(',')
|
||||
|
||||
line = f.readline()
|
||||
while line:
|
||||
board = []
|
||||
for i in range(GRID_SIZE):
|
||||
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_until_win(boards_list, draws):
|
||||
""" play until win and return last pos """
|
||||
|
||||
for d in draws:
|
||||
for board in boards_list:
|
||||
if board.mark_number(d):
|
||||
print("this board wins !")
|
||||
board.print_with_mark()
|
||||
return board, d
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
boards, draws = parse_file('input.txt')
|
||||
print(f'number of boards: {len(boards)}')
|
||||
|
||||
# (winning_board, last_num) = play_until_win(boards, draws)
|
||||
winning_boards = play(boards, draws)
|
||||
|
||||
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}')
|
Loading…
Reference in a new issue