Add 2021-04 Python
This commit is contained in:
parent
3f9158717b
commit
2f3f797d5e
5 changed files with 146 additions and 0 deletions
2
challenges/2021/04-giantSquid/README.md
Normal file
2
challenges/2021/04-giantSquid/README.md
Normal file
|
@ -0,0 +1,2 @@
|
|||
# [Day 4: Giant Squid](https://adventofcode.com/2021/day/4)
|
||||
|
15
challenges/2021/04-giantSquid/benchmark.json
Normal file
15
challenges/2021/04-giantSquid/benchmark.json
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"day": 4,
|
||||
"dir": "challenges/2021/04-giantSquid",
|
||||
"implementations": {
|
||||
"Python": {
|
||||
"part.1.avg": 0.00824344539642334,
|
||||
"part.1.max": 0.020010709762573242,
|
||||
"part.1.min": 0.006531953811645508,
|
||||
"part.2.avg": 0.01698760747909546,
|
||||
"part.2.max": 0.039929866790771484,
|
||||
"part.2.min": 0.013757705688476562
|
||||
}
|
||||
},
|
||||
"numRuns": 500
|
||||
}
|
17
challenges/2021/04-giantSquid/info.json
Normal file
17
challenges/2021/04-giantSquid/info.json
Normal file
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"inputFile": "input.txt",
|
||||
"testCases": {
|
||||
"one": [
|
||||
{
|
||||
"input": "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\n\n22 13 17 11 0\n 8 2 23 4 24\n21 9 14 16 7\n 6 10 3 18 5\n 1 12 20 15 19\n\n 3 15 0 2 22\n 9 18 13 17 5\n19 8 7 25 23\n20 11 10 24 4\n14 21 16 12 6\n\n14 21 17 24 4\n10 16 15 9 19\n18 8 23 26 20\n22 11 13 6 5\n 2 0 12 3 7",
|
||||
"expected": "4512"
|
||||
}
|
||||
],
|
||||
"two": [
|
||||
{
|
||||
"input": "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\n\n22 13 17 11 0\n 8 2 23 4 24\n21 9 14 16 7\n 6 10 3 18 5\n 1 12 20 15 19\n\n 3 15 0 2 22\n 9 18 13 17 5\n19 8 7 25 23\n20 11 10 24 4\n14 21 16 12 6\n\n14 21 17 24 4\n10 16 15 9 19\n18 8 23 26 20\n22 11 13 6 5\n 2 0 12 3 7",
|
||||
"expected": "1924"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
111
challenges/2021/04-giantSquid/py/__init__.py
Normal file
111
challenges/2021/04-giantSquid/py/__init__.py
Normal file
|
@ -0,0 +1,111 @@
|
|||
from typing import List, Tuple, Optional
|
||||
from aocpy import BaseChallenge
|
||||
from dataclasses import dataclass
|
||||
|
||||
|
||||
BOARD_EDGE = 5 # assuming our boards are square, how long is one edge of the board?
|
||||
|
||||
WINNING_SEQUENCES = (
|
||||
(0, 1, 2, 3, 4),
|
||||
(5, 6, 7, 8, 9),
|
||||
(10, 11, 12, 13, 14),
|
||||
(15, 16, 17, 18, 19),
|
||||
(20, 21, 22, 23, 24),
|
||||
(0, 5, 10, 15, 20),
|
||||
(1, 6, 11, 16, 21),
|
||||
(2, 7, 12, 17, 22),
|
||||
(3, 8, 13, 18, 23),
|
||||
(4, 9, 14, 19, 24),
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
class Point:
|
||||
value: int
|
||||
marked: bool
|
||||
|
||||
|
||||
Board = List[Point]
|
||||
|
||||
|
||||
def parse(instr: str) -> Tuple[List[int], List[Board]]:
|
||||
numbers, rawBoards = instr.strip().split("\n", 1)
|
||||
|
||||
numbers = list(map(int, numbers.split(",")))
|
||||
rawBoards = rawBoards.strip().split("\n\n")
|
||||
|
||||
boards = []
|
||||
for rb in rawBoards:
|
||||
boards.append(
|
||||
[Point(int(x), False) for x in rb.replace("\n", " ").split(" ") if x != ""]
|
||||
)
|
||||
|
||||
return numbers, boards
|
||||
|
||||
|
||||
def check_for_winning_boards(boards: List[Board]) -> List[int]:
|
||||
# returns a list of indexes in `boards` that have won.
|
||||
|
||||
winning_boards = []
|
||||
|
||||
for i, board in enumerate(boards):
|
||||
for sequence in WINNING_SEQUENCES:
|
||||
has_sequence = True
|
||||
for n in sequence:
|
||||
has_sequence = has_sequence and board[n].marked
|
||||
|
||||
if has_sequence:
|
||||
winning_boards.append(i)
|
||||
break
|
||||
|
||||
return winning_boards
|
||||
|
||||
|
||||
def calculate_board_score(board: Board, last_called_number: int) -> int:
|
||||
sigma = sum([n.value for n in board if not n.marked])
|
||||
return sigma * last_called_number
|
||||
|
||||
|
||||
def play_round(boards: List[Board], number: int) -> List[Board]:
|
||||
# plays a round of bingo, removes winning boards from `boards` and returns them.
|
||||
|
||||
for board in boards:
|
||||
for board_number in board:
|
||||
if number == board_number.value:
|
||||
board_number.marked = True
|
||||
break # assume each number only exists once in each board
|
||||
|
||||
winning_boards = check_for_winning_boards(boards)
|
||||
o = []
|
||||
for board_number in reversed(sorted(winning_boards)):
|
||||
o.append(boards.pop(board_number))
|
||||
return o
|
||||
|
||||
|
||||
class Challenge(BaseChallenge):
|
||||
@staticmethod
|
||||
def one(instr: str) -> int:
|
||||
numbers, boards = parse(instr)
|
||||
|
||||
for number in numbers:
|
||||
|
||||
winning_boards = play_round(boards, number)
|
||||
if len(winning_boards) != 0:
|
||||
assert len(winning_boards) == 1
|
||||
return calculate_board_score(winning_boards[0], number)
|
||||
|
||||
return -1
|
||||
|
||||
@staticmethod
|
||||
def two(instr: str) -> int:
|
||||
numbers, boards = parse(instr)
|
||||
|
||||
winners = []
|
||||
|
||||
for number in numbers:
|
||||
winners += play_round(boards, number)
|
||||
|
||||
if len(boards) == 0:
|
||||
break
|
||||
|
||||
return calculate_board_score(winners[-1], number)
|
|
@ -13,5 +13,6 @@ Solutions to the [2021 Advent of Code](https://adventofcode.com/2021).
|
|||
| 01 - Sonar Sweep | Complete | [Python](01-sonarSweep/py), [Go](01-sonarSweep/go), [Nim](01-sonarSweep/nim) | Numbers and sliding windows. |
|
||||
| 02 - Dive! | Complete | [Python](02-dive/py), [Go](02-dive/go) | Have this set of instructions and do something sensible with it. |
|
||||
| 03 - Binary Diagnostic | Complete | [Python](03-binaryDiagnostic/py), [Nim](03-binaryDiagnostic/nim) | Bit twiddling aplenty! |
|
||||
| 04 - Giant Squid | Complete | [Python](04-giantSquid/py) | B-I-N-G-O, B-I-N-G-O, B-I-N-G-O and Bingo was his name-o! |
|
||||
|
||||
<!-- PARSE END -->
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue