diff --git a/4/4_2.py b/4/4_2.py new file mode 100755 index 0000000..8d3c407 --- /dev/null +++ b/4/4_2.py @@ -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}')