My advent of code solutions
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

98 lines
2.3 KiB

"""
Advent of Code 2021 - Day 04
Run with:
python puzzles/day04.py inputs/day04.txt
"""
import pathlib
import sys
from typing import Dict, List, Tuple
import numpy as np
class Bingo:
boards: List = []
draws: List = []
game = None
winning_board = None
winning_score = 0
def __init__(self, inputs: str) -> None:
inputs = inputs.split("\n\n")
# Convert all values to int
self.draws = list(map(int, inputs.pop(0).split(",")))
self.boards = np.array(
[
[list(map(int, value.split())) for value in line.split("\n")]
for line in inputs
],
dtype=object,
)
def solve(self) -> int:
self.game = self.boards.copy()
for draw in self._draw():
self.game[self.game == draw] = np.nan
for index, board in enumerate(self.game):
if self._is_solved(board):
self.winning_board = self.boards[index]
self.winning_score = self.calculate_score(board, draw)
return self.winning_score
return 0
def _draw(self) -> int:
for draw in self.draws:
yield draw
@staticmethod
def calculate_score(solved_board, last_draw: int) -> int:
board_score = np.nansum(solved_board)
return board_score * last_draw
@staticmethod
def _is_solved(board) -> bool:
# Solved if any row or column is 0
cols = np.nansum(board, axis=0)
rows = np.nansum(board, axis=1)
if np.count_nonzero(cols) != cols.size or np.count_nonzero(rows) != rows.size:
return True
return False
def part1(inputs: str) -> int:
game = Bingo(inputs)
return game.solve()
def part2(inputs: str) -> int:
game = Bingo(inputs)
return False
def solve(path: str) -> Tuple[int, int]:
"""Solve the puzzle"""
inputs = pathlib.Path(path).read_text().strip()
part1_result = part1(inputs)
part2_result = part2(inputs)
return part1_result, part2_result
def main() -> None:
for path in sys.argv[1:]:
print(f"Input File: {path}")
part1_result, part2_result = solve(path)
print(f"Part 1 Result: {part1_result}")
print(f"Part 2 Result: {part2_result}")
if __name__ == "__main__":
main()