53 lines
1.5 KiB
Python
53 lines
1.5 KiB
Python
import numpy as np
|
|
from numpy.lib.stride_tricks import as_strided
|
|
|
|
from day11.common import char_to_int
|
|
|
|
|
|
def get_filters(arr):
|
|
KERNEL_SHAPE = (3, 3)
|
|
return as_strided(
|
|
arr,
|
|
shape=(
|
|
arr.shape[0] - KERNEL_SHAPE[0] + 1, # The feature map is a few pixels smaller than the input
|
|
arr.shape[1] - KERNEL_SHAPE[1] + 1,
|
|
KERNEL_SHAPE[0],
|
|
KERNEL_SHAPE[1],
|
|
),
|
|
strides=(
|
|
arr.strides[0],
|
|
arr.strides[1],
|
|
arr.strides[0], # When we move one step in the 3rd dimension, we should move one step in the original data too
|
|
arr.strides[1],
|
|
),
|
|
writeable=False, # totally use this to avoid writing to memory in weird places
|
|
)
|
|
|
|
|
|
def parse(arr):
|
|
if arr[1, 1] == 0:
|
|
return 0
|
|
if np.count_nonzero(arr == 1) == 0:
|
|
return 1
|
|
if arr[1, 1] == 1 and np.count_nonzero(arr == 1) >= 5:
|
|
return -1
|
|
return arr[1, 1]
|
|
|
|
|
|
lines = np.array([[char_to_int(x) for x in line.strip()] for line in open("input.txt")], dtype=np.byte)
|
|
lines = np.pad(lines, 1, 'constant', constant_values=0)
|
|
shape = np.array(lines.shape)
|
|
last = -1
|
|
while True:
|
|
curr = np.count_nonzero(lines == 1)
|
|
if curr == last:
|
|
print(last)
|
|
break
|
|
last = curr
|
|
expanded_input = get_filters(lines)
|
|
new_input = np.zeros(shape, dtype=np.byte)
|
|
for idx in np.ndindex(*shape-2):
|
|
target = tuple(np.array(idx) + 1)
|
|
new_input[target] = parse(expanded_input[idx])
|
|
lines = new_input
|