In today's post, I came to the realization that I should have a little library to dealing with 3D coordinates and arrays easier.
I've now created such a library, and redid last night's challenge using it.
In the first challenge, just checking for exposed faces:
import "vector3"
if 0 then fname = "input.txt" else fname = "example.txt"
lines = file.readLines(fname)
if not lines[-1] then lines.pop
cubes = []
volume = list.init3d(21, 21, 21, 0)
for line in lines
pos = line.split(",")
pos.apply @val
cubes.push pos
volume.set pos, 1
end for
count = 0
for cube in cubes.values
for n in vector3.neighbors6
npos = cube.plus(n)
if not volume.get(npos) then count = count + 1
end for
end for
print "Faces: " + count
We now create a volume
(3D array), initialized to 0, changed to 1 wherever we have a cube; we also keep cubes
now as a list (not map) of 3D coordinates. Then we can just iterate over those cubes, checking the neighbors (using our handy new neighbors6
list), and add up how many faces are exposed.
Part 2 is really no harder. We just initialize our volume to value 2, meaning "interior space," and then after loading the cubes, do a floodFill
from the origin to change all the outside space to 0. Then we don't need to change the counting loop at all.
import "vector3"
if 1 then fname = "input.txt" else fname = "example.txt"
lines = file.readLines(fname)
if not lines[-1] then lines.pop
cubes = []
// init volume to value 2, meaning "interior space"
volume = list.init3d(21, 21, 21, 2)
// load cubes
for line in lines
pos = line.split(",")
pos.apply @val
cubes.push pos
volume.set pos, 1
end for
// then flood-fill with 0, meaning "outside air"
volume.floodFill [0,0,0], 0
count = 0
for cube in cubes.values
for n in vector3.neighbors6
npos = cube.plus(n)
if not volume.get(npos) then count = count + 1
end for
end for
print "Faces: " + count
I'm quite happy with the new library; it really does make working with 3D coordinates and arrays a breeze. Here's hoping a need for that will come up again!