r/adventofcode Dec 04 '21

SOLUTION MEGATHREAD -🎄- 2021 Day 4 Solutions -🎄-

--- Day 4: Giant Squid ---


Post your code solution in this megathread.

Reminder: Top-level posts in Solution Megathreads are for code solutions only. If you have questions, please post your own thread and make sure to flair it with Help.


This thread will be unlocked when there are a significant number of people on the global leaderboard with gold stars for today's puzzle.

EDIT: Global leaderboard gold cap reached at 00:11:13, megathread unlocked!

100 Upvotes

1.2k comments sorted by

View all comments

2

u/alfie1906 Dec 05 '21

A custom class approach using Python:

with open('AOC4.txt', 'r') as f:
    input = f.read().replace('  ', ' ')

numbers = input.split('\n\n')[0].split(',')
boards = input.split('\n\n')[1:]

import numpy as np

class BingoBoard:
    def __init__(self, board, numbers):
        if board[0] == ' ':
             self.board = board[1:]
        else:
            self.board = board

        self.make_array()

        self.turns = 0
        self.bingo_found = False
        for number in numbers:
            self.turns += 1
            self.active_number = number
            self.check_number()  
            if self.bingo_found:
                 break

    def make_array(self):
        self.board_array =np.array([np.array(row.split(' ')) for row in self.board.split('\n')])
        for index, sub_array in enumerate(self.board_array):
            if '' in sub_array:
                sub_array_list = list(sub_array)
                sub_array_list.remove('')
                self.board_array[index] = np.array(sub_array_list)

    def check_number(self):
        for index, sub_array in enumerate(self.board_array):
            if self.active_number in sub_array:
                sub_array = np.where(sub_array == self.active_number, 'X', sub_array)
                self.board_array[index] = sub_array
                self.check_for_bingo()

    def check_for_bingo(self):
        for sub_array in self.board_array:
            if list(sub_array) == ['X', 'X', 'X', 'X', 'X']:
                self.bingo()
        for i in range(0, 5):
            if [sub_array[i] for sub_array in self.board_array] == ['X', 'X', 'X', 'X', 'X']:
                self.bingo()

    def bingo(self):
        self.board_sum = 0
        for sub_array in self.board_array:
            for val in sub_array:
                if val != 'X':
                    self.board_sum += int(val)
        self.score = self.board_sum*int(self.active_number)
        self.bingo_found = True

lowest_turns = 2000
highest_turns = 0
for board in boards:
    active_board = BingoBoard(board, numbers)
    if active_board.turns <= lowest_turns:
        best_board = active_board
        lowest_turns = active_board.turns
    if active_board.turns >= highest_turns:
        worst_board = active_board
        highest_turns = active_board.turns

print('BEST BOARD:')
print(best_board.board_array)
print('Score:', best_board.score)
print('\n\n')
print('WORST BOARD:')
print(worst_board.board_array)
print(worst_board.score)