Advent of Code: Day 4
A giant squid appears.
No, really. On Day 4, a giant squid appears and wants to play Bingo with you. This time, there are several Bingo boards and you're given a list of numbers that will be drawn (cheating!). So your goal is to find out which board will win first. Thankfully, with technology's help, this matter shouldn't be too difficult.
def read(filename):
file = open(filename)
numbers = file.readline().split(',')
lines = file.read().splitlines()
rows = [line.split() for line in lines if line]
boards = []
while len(rows):
boards.append(rows[:5])
rows = rows[5:]
return numbers, boards
def fill_board(board, number):
for i in range(5):
for j in range(5):
if board[i][j] == number:
board[i][j] = None
def board_wins(board):
# Check rows
for i in range(5):
win = True
for j in range(5):
if board[i][j] is not None:
win = False
break
if win:
return True
# Check columns
for j in range(5):
win = True
for i in range(5):
if board[i][j] is not None:
win = False
break
if win:
return True
return False
def solve(numbers, boards):
for number in numbers:
for board in boards:
fill_board(board, number)
if board_wins(board):
summary = sum([sum([int(number) for number in row if number is not None]) for row in board])
print(summary * int(number))
return
numbers, boards = read('input.txt')
solve(numbers, boards)
In Part 2, turns out some in your crew apparently watched Squid Game, and they don't want to anger the squid for fear of bad things happening. So they want you to help it win. And this time we will try to determine which board will win last.
def read(filename):
file = open(filename)
numbers = file.readline().split(',')
lines = file.read().splitlines()
rows = [line.split() for line in lines if line]
boards = []
while len(rows):
boards.append(rows[:5])
rows = rows[5:]
return numbers, boards
def fill_board(board, number):
for i in range(5):
for j in range(5):
if board[i][j] == number:
board[i][j] = None
def board_wins(board):
if board[0][0] == '-1':
return False
# Check rows
for i in range(5):
win = True
for j in range(5):
if board[i][j] is not None:
win = False
break
if win:
return True
# Check columns
for j in range(5):
win = True
for i in range(5):
if board[i][j] is not None:
win = False
break
if win:
return True
return False
# Mark board removed by filling first number with '-1'
def remove_board(board):
board[0][0] = '-1'
def solve(numbers, boards):
boards_won = 0
for number in numbers:
for board in boards:
fill_board(board, number)
if board_wins(board):
boards_won += 1
if boards_won == len(boards):
summary = sum([sum([int(number) for number in row if number is not None]) for row in board])
print(summary * int(number))
return
# Remove this board from boards
remove_board(board)
numbers, boards = read('input.txt')
solve(numbers, boards)
Takeaways
Surprisingly, this game has provided me with some clarity on programming and how to optimize for this kind of competition. Specifically, here are the rules I set for myself in future days of Advent of Code:
Variables will contain data that match their names and descriptions.
Use functions. As a newcomer to Python, I tend to do what beginners do: write everything in one block from top to bottom. As it turns out, learning and using a more procedural style make all this more manageable and effective.
Take in strides. This means no longer frantically try to code as fast as I can. I made this mistake in Day 3, which made my coding experience worse and actually prolonged the time to solution. This time, with all experience equipped so far, I will read the problem carefully, take leisure in mapping out the solution, and code in professional business method, not code golf.
If you're reading this and want to join us, there's still time. If you've beaten Day 4, congratulations and thanks for the companionship.