53 lines
1.4 KiB
Python
53 lines
1.4 KiB
Python
import numpy as np
|
|
|
|
def read_map(filename: str):
|
|
# Read file as list of strings
|
|
with open(filename, "r") as fp:
|
|
data = fp.read().splitlines()
|
|
|
|
# Use Numpy to make it a 2D array of characters
|
|
tp_str_map = np.array(data, dtype=str)\
|
|
.view("U1")\
|
|
.reshape((len(data), -1))
|
|
|
|
# Make it a boolean map
|
|
tp_map = np.zeros_like(tp_str_map, dtype=bool)
|
|
tp_map[tp_str_map == "@"] = True
|
|
return tp_map
|
|
|
|
def print_map(tp_map):
|
|
view = np.zeros_like(tp_map, dtype="U1")
|
|
view[tp_map] = "@"
|
|
view[~tp_map] = "."
|
|
for i in range(view.shape[0]):
|
|
for j in range(view.shape[1]):
|
|
print(view[i,j], end="")
|
|
print()
|
|
|
|
def count_neighbours(tp_map):
|
|
delta1D = np.array([-1, 0, 1])
|
|
X, Y = np.meshgrid(delta1D, delta1D)
|
|
neighbour_counts = np.zeros_like(tp_map, dtype=int)
|
|
|
|
for x, y in np.ndindex(tp_map.shape):
|
|
if not tp_map[x,y]:
|
|
continue
|
|
L_x, L_y = tp_map.shape
|
|
dX, dY = X.copy() + x, Y.copy() + y
|
|
legal_idx = (dX >= 0)*(dX < L_x)*(dY >= 0)*(dY < L_y)*((dX != x)|(dY != y))
|
|
neighbour_counts[x, y] = (tp_map[dX[legal_idx], dY[legal_idx]]).sum()
|
|
return neighbour_counts
|
|
|
|
def count_extractable(tp_map):
|
|
neighbour_counts = count_neighbours(tp_map)
|
|
max_rolls = 4
|
|
return (neighbour_counts[tp_map] < max_rolls).sum()
|
|
|
|
if __name__ == "__main__":
|
|
test_map = read_map("testinput")
|
|
# print(test_map)
|
|
assert count_extractable(test_map) == 13
|
|
# TODO: Compare the output map.
|
|
|
|
real_map = read_map("input")
|
|
print(count_extractable(real_map)) |