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