import numpy lava = numpy.zeros((23,23,23), dtype=numpy.int32) for line in open("input"): x,y,z = map(int, line.strip().split(",")) lava[x,y,z] = 1 water = numpy.zeros((23,23,23), dtype=numpy.int32) area = 0 N = 23 for x in range(N): for y in range(N): for z in range(N): if lava[x,y,z]: sides = 0 def do(x,y,z): global sides if 0 <= x < N and 0 <= y < N and 0 <= z < N: sides += not lava[x,y,z] else: sides += 1 do(x-1, y, z) do(x+1, y, z) do(x, y-1, z) do(x, y+1, z) do(x, y, z-1) do(x, y, z+1) area += sides else: if 0 in (x,y,z) or N-1 in (x,y,z): water[x,y,z] = 1 print(area) def move(w, axis, amount): w = numpy.roll(w, amount, axis=axis) all = slice(None,None) index = [all,all,all] if amount > 1: index[axis] = 0 else: index[axis] = w.shape[axis] - 1 w[tuple(index)] = 0 return w def flood(a): while True: x = move(a, 0, -1) x |= move(a, 0, +1) x |= move(a, 1, -1) x |= move(a, 1, +1) x |= move(a, 2, -1) x |= move(a, 2, +1) x = x & ~lava if (a == x).all(): return a a = x print(move(numpy.ones((3,3,3)), 1, 1)) print(move(numpy.ones((3,3,3)), 0, -1)) water = flood(water) print(water) area = 0 N = 23 for x in range(N): for y in range(N): for z in range(N): if lava[x,y,z]: sides = 0 def do(x,y,z): global sides if 0 <= x < N and 0 <= y < N and 0 <= z < N: sides += not lava[x,y,z] and water[x,y,z] else: sides += 1 do(x-1, y, z) do(x+1, y, z) do(x, y-1, z) do(x, y+1, z) do(x, y, z-1) do(x, y, z+1) area += sides else: if 0 in (x,y,z) or N-1 in (x,y,z): water[x,y,z] = 1 print(area)