Public
Edited
Dec 2, 2024
Paused
1 fork
1 star
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function extents(coords) {
return [
Math.max(...coords.map((c) => c[0])),
Math.max(...coords.map((c) => c[1])),
Math.max(...coords.map((c) => c[2]))
];
}
Insert cell
Insert cell
function parse(input) {
return input.split("\n").map((l) => l.split(",").map((t) => Number(t) + 1));
}
Insert cell
Insert cell
function toVolume(coords, space = 0) {
const [xMax, yMax, zMax] = extents(coords);
const vol = Array(xMax + 2)
.fill(0)
.map((x) => AOC.gInit(yMax + 2, zMax + 2, space));

coords.forEach(([x, y, z]) => (vol[x][y][z] = 1));
return vol;
}
Insert cell
Insert cell
function neighbours([x, y, z], vol) {
return [
vol[x + 1] === undefined ? [] : [x + 1, y, z],
vol[x - 1] === undefined ? [] : [x - 1, y, z],
vol[x][y - 1] === undefined ? [] : [x, y - 1, z],
vol[x][y + 1] === undefined ? [] : [x, y + 1, z],
vol[x][y][z - 1] === undefined ? [] : [x, y, z - 1],
vol[x][y][z + 1] === undefined ? [] : [x, y, z + 1]
].filter((c) => c.length > 0);
}
Insert cell
Insert cell
function surfaceArea(coords, vol) {
return coords.reduce(
(area, p) =>
area +
6 -
neighbours(p, vol).filter(([x, y, z]) => vol[x][y][z] === 1).length,
0
);
}
Insert cell
function part1(input) {
const coords = parse(input);
return surfaceArea(coords, toVolume(coords));
}
Insert cell
Insert cell
Insert cell
Insert cell
function outerVolume(coords) {
const vol = toVolume(coords); // Voume of scanned lava
const outerVol = toVolume(coords, 1); // Solid cube
const toStr = ([x, y, z]) => x + "," + y + "," + z;

// Breadth-first search of all empty voxels
const [todo, visited] = [[[0, 0, 0]], new Set()];
while (todo.length > 0) {
const [x, y, z] = todo.shift();
const pStr = toStr([x, y, z]);
if (!visited.has(pStr)) {
visited.add(pStr);
if (vol[x][y][z] === 0) {
outerVol[x][y][z] = 0; // Empty this voxel in the solid cube
neighbours([x, y, z], vol).forEach(([nx, ny, nz]) => {
if (!visited.has(toStr([nx, ny, nz]))) {
todo.push([nx, ny, nz]);
}
});
}
}
}
return outerVol;
}
Insert cell
function part2(input) {
const coords = parse(input);
return surfaceArea(coords, outerVolume(coords));
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more