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.

51 lines
1.6 KiB

import numpy as np
def readInput(fileName) -> tuple[np.ndarray, np.ndarray]:
with open(fileName) as file:
allLines = file.read().splitlines()
algorithm = np.fromstring(allLines[0].replace(".", "0 ").replace("#", "1 "), int, sep=" ")
image = np.array([list(line.replace(".", "0").replace("#", "1")) for line in allLines[2:]], dtype=int)
return algorithm, image
def apply(algorithm: np.ndarray, image: np.ndarray, fillValue: int) -> tuple[np.ndarray, int]:
# we need to add two more elements on every side
toReadFrom = np.pad(image, 2, constant_values=fillValue)
# stride must contain 3x3 array of neighbour elements for each non-border element in toReadFrom (2D x 2D)
strideSize = toReadFrom.shape[0] - 2
strideShape = strideSize, strideSize, 3, 3
stride = np.lib.stride_tricks.as_strided(toReadFrom, strideShape, 2 * toReadFrom.strides)
# flatten 3x3 values
stride = np.reshape(stride, (strideSize, strideSize, 9))
# convert right 8 bits into decimal with np.packbits (only supports np.uint8), add 256 or 0
codes = stride[:, :, 0] * 256 + np.packbits(stride[:, :, 1:]).reshape(strideSize, strideSize)
newImage = algorithm[codes]
# if fillValue is 0, take the first, if 1, take the last
newFillValue = algorithm[fillValue * 511]
return newImage, newFillValue
def solve():
algorithm, startImage = readInput("input")
# Task 1
nextImage, newFillValue = apply(algorithm, startImage, 0)
finalImage, _ = apply(algorithm, nextImage, newFillValue)
print(np.count_nonzero(finalImage))
# Task 2
image = startImage
fillValue = 0
for _ in range(50):
image, fillValue = apply(algorithm, image, fillValue)
print(np.count_nonzero(image))
solve()