advent-of-code/src/holt59/aoc/2022/day18.py

59 lines
1.4 KiB
Python
Raw Permalink Normal View History

from typing import Any, Iterator
2022-12-18 08:57:35 +00:00
import numpy as np
from ..base import BaseSolver
2022-12-18 08:57:35 +00:00
class Solver(BaseSolver):
def solve(self, input: str) -> Iterator[Any]:
xyz = np.asarray(
[
tuple(int(x) for x in row.split(",")) # type: ignore
for row in input.splitlines()
]
)
2022-12-18 08:57:35 +00:00
xyz = xyz - xyz.min(axis=0) + 1
2022-12-18 08:57:35 +00:00
cubes = np.zeros(xyz.max(axis=0) + 3, dtype=bool)
cubes[xyz[:, 0], xyz[:, 1], xyz[:, 2]] = True
2022-12-18 08:57:35 +00:00
faces = [(-1, 0, 0), (1, 0, 0), (0, -1, 0), (0, 1, 0), (0, 0, -1), (0, 0, 1)]
2022-12-18 08:57:35 +00:00
yield sum(
1
for x, y, z in xyz
for dx, dy, dz in faces
if not cubes[x + dx, y + dy, z + dz]
)
2022-12-18 08:57:35 +00:00
visited = np.zeros_like(cubes, dtype=bool)
queue = [(0, 0, 0)]
2022-12-18 08:57:35 +00:00
n_faces = 0
while queue:
x, y, z = queue.pop(0)
2022-12-18 08:57:35 +00:00
if visited[x, y, z]:
continue
2022-12-18 08:57:35 +00:00
visited[x, y, z] = True
2022-12-18 08:57:35 +00:00
for dx, dy, dz in faces:
nx, ny, nz = x + dx, y + dy, z + dz
if not all(
n >= 0 and n < cubes.shape[i] for i, n in enumerate((nx, ny, nz))
):
continue
2022-12-18 08:57:35 +00:00
if visited[nx, ny, nz]:
continue
if cubes[nx, ny, nz]:
n_faces += 1
else:
queue.append((nx, ny, nz))
yield n_faces