Solution to problem 4 part 1 in Python and WIP for part 2)
This commit is contained in:
parent
13c4f1bced
commit
263e451804
202
src/Year_2021/P4.py
Normal file
202
src/Year_2021/P4.py
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
# --- Day 4: Giant Squid ---
|
||||||
|
|
||||||
|
# You're already almost 1.5km (almost a mile) below the surface of the ocean,
|
||||||
|
# already so deep that you can't see any sunlight. What you can see, however,
|
||||||
|
# is a giant squid that has attached itself to the outside of your submarine.
|
||||||
|
|
||||||
|
# Maybe it wants to play bingo?
|
||||||
|
|
||||||
|
# Bingo is played on a set of boards each consisting of a 5x5 grid of numbers.
|
||||||
|
# Numbers are chosen at random, and the chosen number is marked on all boards
|
||||||
|
# on which it appears. (Numbers may not appear on all boards.) If all numbers
|
||||||
|
# in any row or any column of a board are marked, that board wins. (Diagonals
|
||||||
|
# don't count.)
|
||||||
|
|
||||||
|
# The submarine has a bingo subsystem to help passengers (currently, you and
|
||||||
|
# the giant squid) pass the time. It automatically generates a random order in
|
||||||
|
# which to draw numbers and a random set of boards (your puzzle input). For
|
||||||
|
# example:
|
||||||
|
|
||||||
|
# 7,4,9,5,11,17,23,2,0,14,21,24,10,16,13,6,15,25,12,22,18,20,8,19,3,26,1
|
||||||
|
|
||||||
|
# 22 13 17 11 0
|
||||||
|
# 8 2 23 4 24
|
||||||
|
# 21 9 14 16 7
|
||||||
|
# 6 10 3 18 5
|
||||||
|
# 1 12 20 15 19
|
||||||
|
|
||||||
|
# 3 15 0 2 22
|
||||||
|
# 9 18 13 17 5
|
||||||
|
# 19 8 7 25 23
|
||||||
|
# 20 11 10 24 4
|
||||||
|
# 14 21 16 12 6
|
||||||
|
|
||||||
|
# 14 21 17 24 4
|
||||||
|
# 10 16 15 9 19
|
||||||
|
# 18 8 23 26 20
|
||||||
|
# 22 11 13 6 5
|
||||||
|
# 2 0 12 3 7
|
||||||
|
|
||||||
|
# After the first five numbers are drawn (7, 4, 9, 5, and 11), there are no
|
||||||
|
# winners, but the boards are marked as follows (shown here adjacent to each
|
||||||
|
# other to save space):
|
||||||
|
|
||||||
|
# 22 13 17 11 0 3 15 0 2 22 14 21 17 24 4
|
||||||
|
# 8 2 23 4 24 9 18 13 17 5 10 16 15 9 19
|
||||||
|
# 21 9 14 16 7 19 8 7 25 23 18 8 23 26 20
|
||||||
|
# 6 10 3 18 5 20 11 10 24 4 22 11 13 6 5
|
||||||
|
# 1 12 20 15 19 14 21 16 12 6 2 0 12 3 7
|
||||||
|
|
||||||
|
# After the next six numbers are drawn (17, 23, 2, 0, 14, and 21), there are
|
||||||
|
# still no winners:
|
||||||
|
|
||||||
|
# 22 13 17 11 0 3 15 0 2 22 14 21 17 24 4
|
||||||
|
# 8 2 23 4 24 9 18 13 17 5 10 16 15 9 19
|
||||||
|
# 21 9 14 16 7 19 8 7 25 23 18 8 23 26 20
|
||||||
|
# 6 10 3 18 5 20 11 10 24 4 22 11 13 6 5
|
||||||
|
# 1 12 20 15 19 14 21 16 12 6 2 0 12 3 7
|
||||||
|
|
||||||
|
# Finally, 24 is drawn:
|
||||||
|
|
||||||
|
# 22 13 17 11 0 3 15 0 2 22 14 21 17 24 4
|
||||||
|
# 8 2 23 4 24 9 18 13 17 5 10 16 15 9 19
|
||||||
|
# 21 9 14 16 7 19 8 7 25 23 18 8 23 26 20
|
||||||
|
# 6 10 3 18 5 20 11 10 24 4 22 11 13 6 5
|
||||||
|
# 1 12 20 15 19 14 21 16 12 6 2 0 12 3 7
|
||||||
|
|
||||||
|
# At this point, the third board wins because it has at least one complete row
|
||||||
|
# or column of marked numbers (in this case, the entire top row is marked:
|
||||||
|
# 14 21 17 24 4).
|
||||||
|
|
||||||
|
# The score of the winning board can now be calculated. Start by finding the
|
||||||
|
# sum of all unmarked numbers on that board; in this case, the sum is 188.
|
||||||
|
# Then, multiply that sum by the number that was just called when the board
|
||||||
|
# won, 24, to get the final score, 188 * 24 = 4512.
|
||||||
|
|
||||||
|
# To guarantee victory against the giant squid, figure out which board will win
|
||||||
|
# first. What will your final score be if you choose that board?
|
||||||
|
|
||||||
|
from itertools import chain, zip_longest
|
||||||
|
|
||||||
|
with open("files/P4.txt", "r") as f:
|
||||||
|
data = [line for line in f.read().strip().split("\n\n")]
|
||||||
|
numbers, all_boards = data[0].split(","), [
|
||||||
|
board.split("\n") for board in data[1:]
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def iter_to_list(lst):
|
||||||
|
return [tuple(tup.split()) for tup in lst]
|
||||||
|
|
||||||
|
|
||||||
|
def transpose_board(lst):
|
||||||
|
args = iter_to_list(lst)
|
||||||
|
return list(zip_longest(*args))
|
||||||
|
|
||||||
|
|
||||||
|
def check_num(board, number):
|
||||||
|
flatten_list = list(chain.from_iterable(board))
|
||||||
|
for num in flatten_list:
|
||||||
|
if int(num.rjust(2, "0")) == int(number):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def complete_row(lst, board):
|
||||||
|
for num in lst:
|
||||||
|
if num not in board:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def sum_board(board, row, lst):
|
||||||
|
flatten_list = set(chain.from_iterable(board))
|
||||||
|
row_set = set(row)
|
||||||
|
remain = flatten_list - row_set
|
||||||
|
return sum(int(number) for number in list(remain) if number not in lst)
|
||||||
|
|
||||||
|
|
||||||
|
boards = [iter_to_list(board) for board in all_boards]
|
||||||
|
boards_transpose = [transpose_board(board) for board in all_boards]
|
||||||
|
|
||||||
|
|
||||||
|
def part_1():
|
||||||
|
numbers_drawn = []
|
||||||
|
for number in numbers:
|
||||||
|
numbers_drawn.append(number)
|
||||||
|
if len(numbers_drawn) < 5:
|
||||||
|
continue
|
||||||
|
for b, bt in zip(boards, boards_transpose):
|
||||||
|
for row_b, row_bt in zip(b, bt):
|
||||||
|
if complete_row(row_b, numbers_drawn):
|
||||||
|
return print(
|
||||||
|
sum_board(b, row_b, numbers_drawn)
|
||||||
|
* int(numbers_drawn[-1])
|
||||||
|
)
|
||||||
|
if complete_row(row_bt, numbers_drawn):
|
||||||
|
return print(
|
||||||
|
sum_board(bt, row_bt, numbers_drawn)
|
||||||
|
* int(numbers_drawn[-1])
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# --- Part Two ---
|
||||||
|
|
||||||
|
# On the other hand, it might be wise to try a different strategy: let the
|
||||||
|
# giant squid win.
|
||||||
|
|
||||||
|
# You aren't sure how many bingo boards a giant squid could play at once, so
|
||||||
|
# rather than waste time counting its arms, the safe thing to do is to figure
|
||||||
|
# out which board will win last and choose that one. That way, no matter which
|
||||||
|
# boards it picks, it will win for sure.
|
||||||
|
|
||||||
|
# In the above example, the second board is the last to win, which happens
|
||||||
|
# after 13 is eventually called and its middle column is completely marked. If
|
||||||
|
# you were to keep playing until this point, the second board would have a sum
|
||||||
|
# of unmarked numbers equal to 148 for a final score of 148 * 13 = 1924.
|
||||||
|
|
||||||
|
# Figure out which board will win last. Once it wins, what would its final
|
||||||
|
# score be?
|
||||||
|
|
||||||
|
|
||||||
|
def part_2():
|
||||||
|
(numbers_drawn,) = []
|
||||||
|
for number in numbers:
|
||||||
|
numbers_drawn.append(number)
|
||||||
|
if len(numbers_drawn) < 5:
|
||||||
|
continue
|
||||||
|
for b, bt in zip(boards, boards_transpose):
|
||||||
|
for row_b, row_bt in zip(b, bt):
|
||||||
|
if complete_row(row_b, numbers_drawn):
|
||||||
|
# wining_boards.append(
|
||||||
|
# (b, row_b, numbers_drawn[-1], numbers_drawn)
|
||||||
|
# )
|
||||||
|
total = print(
|
||||||
|
sum_board(b, row_b, numbers_drawn)
|
||||||
|
* int(numbers_drawn[-1])
|
||||||
|
)
|
||||||
|
if total is not None and total > 0:
|
||||||
|
print(total)
|
||||||
|
if complete_row(row_bt, numbers_drawn):
|
||||||
|
# wining_boards.append(
|
||||||
|
# (bt, row_bt, numbers_drawn[-1], numbers_drawn)
|
||||||
|
# )
|
||||||
|
total = print(
|
||||||
|
sum_board(bt, row_bt, numbers_drawn)
|
||||||
|
* int(numbers_drawn[-1])
|
||||||
|
)
|
||||||
|
if total is not None and total > 0:
|
||||||
|
print(total)
|
||||||
|
# b, r, n, nd = wining_boards[0]
|
||||||
|
# # print(b, r, n)
|
||||||
|
# print(sum_board(b, r, nd) * int(n))
|
||||||
|
# # last_board, row = wining_boards[-1]
|
||||||
|
# # print(last_board, row, numbers_drawn[-1])
|
||||||
|
# # return print(sum_board(last_board, row, numbers_drawn)) * int(
|
||||||
|
# # numbers_drawn[-1]
|
||||||
|
# # )
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
part_1()
|
||||||
|
part_2()
|
Loading…
Reference in New Issue
Block a user