mirror of
https://github.com/bertptrs/adventofcode.git
synced 2025-12-25 21:00:31 +01:00
2019 day 24 part 1
This commit is contained in:
58
2019/aoc2019/day24.py
Normal file
58
2019/aoc2019/day24.py
Normal file
@@ -0,0 +1,58 @@
|
||||
from typing import TextIO, Iterable, Tuple
|
||||
|
||||
|
||||
def read_board(data: TextIO) -> Tuple[Tuple[bool]]:
|
||||
return tuple(
|
||||
tuple(c == '#' for c in line.strip())
|
||||
for line in data
|
||||
)
|
||||
|
||||
|
||||
def flatten(it: Iterable[Iterable]) -> Iterable:
|
||||
for item in it:
|
||||
yield from item
|
||||
|
||||
|
||||
def neighbours(board: Tuple[Tuple[bool]], x: int, y: int) -> int:
|
||||
n = 0
|
||||
|
||||
if x > 0 and board[y][x - 1]:
|
||||
n += 1
|
||||
|
||||
if x + 1 < len(board[0]) and board[y][x + 1]:
|
||||
n += 1
|
||||
|
||||
if y > 0 and board[y - 1][x]:
|
||||
n += 1
|
||||
|
||||
if y + 1 < len(board) and board[y + 1][x]:
|
||||
n += 1
|
||||
|
||||
return n
|
||||
|
||||
|
||||
def advance_board(board: Tuple[Tuple[bool]]) -> Tuple[Tuple[bool]]:
|
||||
def create_row(y: int, row: Tuple[bool]):
|
||||
new_row = []
|
||||
for x, live in enumerate(row):
|
||||
if live:
|
||||
new_row.append(neighbours(board, x, y) == 1)
|
||||
else:
|
||||
new_row.append(neighbours(board, x, y) in [1, 2])
|
||||
|
||||
return tuple(new_row)
|
||||
|
||||
return tuple(create_row(y, row) for y, row in enumerate(board))
|
||||
|
||||
|
||||
def part1(data: TextIO) -> int:
|
||||
board = read_board(data)
|
||||
|
||||
seen = set(board)
|
||||
|
||||
while True:
|
||||
board = advance_board(board)
|
||||
if board in seen:
|
||||
return sum(2 ** i for i, b in enumerate(flatten(board)) if b)
|
||||
|
||||
seen.add(board)
|
||||
64
2019/tests/test_day24.py
Normal file
64
2019/tests/test_day24.py
Normal file
@@ -0,0 +1,64 @@
|
||||
import io
|
||||
|
||||
import pytest
|
||||
|
||||
from aoc2019.day24 import read_board, advance_board, part1
|
||||
|
||||
SAMPLE_START = """\
|
||||
....#
|
||||
#..#.
|
||||
#..##
|
||||
..#..
|
||||
#....
|
||||
"""
|
||||
|
||||
SAMPLE_STATES = """\
|
||||
....#
|
||||
#..#.
|
||||
#..##
|
||||
..#..
|
||||
#....
|
||||
|
||||
#..#.
|
||||
####.
|
||||
###.#
|
||||
##.##
|
||||
.##..
|
||||
|
||||
#####
|
||||
....#
|
||||
....#
|
||||
...#.
|
||||
#.###
|
||||
|
||||
#....
|
||||
####.
|
||||
...##
|
||||
#.##.
|
||||
.##.#
|
||||
|
||||
####.
|
||||
....#
|
||||
##..#
|
||||
.....
|
||||
##...
|
||||
""".split("\n\n")
|
||||
|
||||
|
||||
@pytest.mark.parametrize("cycles,state", enumerate(SAMPLE_STATES))
|
||||
def test_evolution_part1(cycles: int, state: str) -> None:
|
||||
with io.StringIO(SAMPLE_START) as f:
|
||||
board = read_board(f)
|
||||
|
||||
with io.StringIO(state) as f:
|
||||
final_state = read_board(f)
|
||||
|
||||
for _ in range(cycles):
|
||||
board = advance_board(board)
|
||||
|
||||
assert board == final_state
|
||||
|
||||
|
||||
def test_sample_part1() -> None:
|
||||
with io.StringIO(SAMPLE_START) as f:
|
||||
assert part1(f) == 2129920
|
||||
Reference in New Issue
Block a user