137 lines
3.4 KiB
Python
137 lines
3.4 KiB
Python
#!/usr/bin/python3
|
|
|
|
def read_boards(input):
|
|
boards = list()
|
|
board = list()
|
|
row = 0
|
|
for line in input:
|
|
if not line.rstrip():
|
|
boards.append(board)
|
|
board = list()
|
|
row = 0
|
|
continue
|
|
col = 0
|
|
for number in line.split():
|
|
field = dict()
|
|
field['number'] = int(number)
|
|
field['marked'] = False
|
|
field['row'] = row
|
|
field['col'] = col
|
|
col += 1
|
|
board.append(field)
|
|
row += 1
|
|
return boards
|
|
|
|
|
|
def mark_number(boards, number):
|
|
for board in boards:
|
|
for field in board:
|
|
if field['number'] == number:
|
|
field['marked'] = True
|
|
return boards
|
|
|
|
|
|
def check_board(board, num_rows, num_cols):
|
|
for row in range(num_rows):
|
|
win = True
|
|
for field in board:
|
|
if not field['marked']:
|
|
if field['row'] == row:
|
|
win = False
|
|
if win:
|
|
return True
|
|
for col in range(num_cols):
|
|
win = True
|
|
for field in board:
|
|
if not field['marked']:
|
|
if field['col'] == col:
|
|
win = False
|
|
if win:
|
|
return True
|
|
return False
|
|
|
|
|
|
def get_board_sum(board):
|
|
sum = 0
|
|
for field in board:
|
|
if not field['marked']:
|
|
sum += field['number']
|
|
return sum
|
|
|
|
|
|
def check_boards(boards, num_rows, num_cols):
|
|
for board in boards:
|
|
for row in range(num_rows):
|
|
win = True
|
|
sum = 0
|
|
for field in board:
|
|
if not field['marked']:
|
|
if field['row'] == row:
|
|
win = False
|
|
sum += field['number']
|
|
if win:
|
|
return sum
|
|
for col in range(num_cols):
|
|
win = True
|
|
sum = 0
|
|
for field in board:
|
|
if not field['marked']:
|
|
if field['col'] == col:
|
|
win = False
|
|
sum += field['number']
|
|
if win:
|
|
return sum
|
|
return 0
|
|
|
|
|
|
def part_1(input):
|
|
result = 0
|
|
drawn = input[0].split(',')
|
|
input.remove(input[0])
|
|
input.remove(input[0])
|
|
boards = read_boards(input)
|
|
for number in drawn:
|
|
number = int(number)
|
|
end = False
|
|
boards = mark_number(boards, number)
|
|
for board in boards:
|
|
if check_board(board, 5, 5):
|
|
end = True
|
|
result = get_board_sum(board) * number
|
|
break
|
|
if end:
|
|
break
|
|
print("Part 1 result:", result)
|
|
|
|
|
|
def part_2(input):
|
|
result = 0
|
|
drawn = input[0].split(',')
|
|
input.remove(input[0])
|
|
input.remove(input[0])
|
|
boards = read_boards(input)
|
|
last_board = list()
|
|
for number in drawn:
|
|
number = int(number)
|
|
boards = mark_number(boards, number)
|
|
num_complete = 0
|
|
for board in boards:
|
|
if check_board(board, 5, 5):
|
|
num_complete += 1
|
|
if len(boards) - num_complete == 1:
|
|
for board in boards:
|
|
if not check_board(board, 5, 5):
|
|
last_board = board
|
|
elif last_board and len(boards) == num_complete:
|
|
result = get_board_sum(last_board) * number
|
|
break
|
|
print("Part 2 result:", result)
|
|
|
|
|
|
input = list()
|
|
with open('input.txt') as fp:
|
|
input = fp.readlines()
|
|
|
|
part_1(input.copy())
|
|
part_2(input.copy())
|