67 lines
1.6 KiB
Python
67 lines
1.6 KiB
Python
import itertools
|
|
import sys
|
|
|
|
import numpy as np
|
|
from numpy.typing import NDArray
|
|
|
|
grid0 = np.array([[c == "#" for c in line] for line in sys.stdin.read().splitlines()])
|
|
|
|
# add an always off circle around
|
|
grid0 = np.concatenate(
|
|
[
|
|
np.zeros((grid0.shape[0] + 2, 1), dtype=bool),
|
|
np.concatenate(
|
|
[
|
|
np.zeros((1, grid0.shape[1]), dtype=bool),
|
|
grid0,
|
|
np.zeros((1, grid0.shape[1]), dtype=bool),
|
|
]
|
|
),
|
|
np.zeros((grid0.shape[0] + 2, 1), dtype=bool),
|
|
],
|
|
axis=1,
|
|
)
|
|
|
|
moves = list(itertools.product([-1, 0, 1], repeat=2))
|
|
moves.remove((0, 0))
|
|
|
|
jjs, iis = np.meshgrid(
|
|
np.arange(1, grid0.shape[0] - 1, dtype=int),
|
|
np.arange(1, grid0.shape[1] - 1, dtype=int),
|
|
)
|
|
iis, jjs = iis.flatten(), jjs.flatten()
|
|
|
|
ins = iis[:, None] + np.array(moves)[:, 0]
|
|
jns = jjs[:, None] + np.array(moves)[:, 1]
|
|
|
|
|
|
def game_of_life(grid: NDArray[np.bool_]) -> NDArray[np.bool_]:
|
|
neighbors_on = grid[ins, jns].sum(axis=1)
|
|
cells_on = grid[iis, jjs]
|
|
|
|
grid = np.zeros_like(grid)
|
|
grid[iis, jjs] = (neighbors_on == 3) | (cells_on & (neighbors_on == 2))
|
|
|
|
return grid
|
|
|
|
|
|
grid = grid0
|
|
n_steps = 4 if len(grid) < 10 else 100
|
|
for _ in range(n_steps):
|
|
grid = game_of_life(grid)
|
|
|
|
answer_1 = grid.sum()
|
|
print(f"answer 1 is {answer_1}")
|
|
|
|
|
|
n_steps = 5 if len(grid) < 10 else 100
|
|
grid = grid0
|
|
for _ in range(n_steps):
|
|
grid[[1, 1, -2, -2], [1, -2, 1, -2]] = True
|
|
grid = game_of_life(grid)
|
|
|
|
grid[[1, 1, -2, -2], [1, -2, 1, -2]] = True
|
|
|
|
answer_2 = sum(cell for line in grid for cell in line)
|
|
print(f"answer 2 is {answer_2}")
|