Published
Edited
Dec 17, 2020
Insert cell
Insert cell
Insert cell
get = (space, z, y, x) => {
return (
space.get(z) &&
space.get(z).get(y) &&
space
.get(z)
.get(y)
.get(x)
);
}
Insert cell
set = (space, z, y, x, val) => {
let zSpace = space.get(z);
if (!zSpace) {
space.set(z, new Map().set(y, new Map().set(x, val)));
return;
}
let ySpace = zSpace.get(y);
if (!ySpace) {
zSpace.set(y, new Map().set(x, val));
return;
}
ySpace.set(x, val);
}
Insert cell
parse = input => {
const space = new Map();
const grid = input.split('\n').map(r => r.split(''));
for (let i = 0; i < grid.length; i++) {
for (let j = 0; j < grid[i].length; j++) {
if (grid[i][j] === '#') set(space, 0, i, j, true);
}
}
return space;
}
Insert cell
parse(testInput)
Insert cell
deltas = {
const out = [];
for (let i = 0; i < 27; i++) {
if (i === 13) continue; // don't want [0,0,0]
out.push(
i
.toString(3) // trinary, e.g. 7 = 21
.padStart(3, '0') // left pad 021
.split('') // [ '0', '2', '1' ]
.map(n => parseInt(n) - 1) // [ -1, 1, 0 ]
);
}
return out;
}
Insert cell
activeNeighbors = (space, z, y, x) => {
return deltas.filter(([deltaZ, deltaY, deltaX]) =>
get(space, z + deltaZ, y + deltaY, x + deltaX)
).length;
}
Insert cell
activeNeighbors(parse(testInput), 0, 0, 1)
Insert cell
spaceRange = space => {
const range = {
minX: Infinity,
minY: Infinity,
minZ: Infinity,
maxX: -Infinity,
maxY: -Infinity,
maxZ: -Infinity
};
space.forEach((ySpace, z) => {
if (z < range.minZ) range.minZ = z;
if (z > range.maxZ) range.maxZ = z;
ySpace.forEach((xSpace, y) => {
if (y < range.minY) range.minY = y;
if (y > range.maxY) range.maxY = y;
xSpace.forEach((val, x) => {
if (x < range.minX) range.minX = x;
if (x > range.maxX) range.maxX = x;
});
});
});
return range;
}
Insert cell
spaceRange(parse(testInput))
Insert cell
step = space => {
const newSpace = new Map();
const { minX, minY, minZ, maxX, maxY, maxZ } = spaceRange(space);
for (let z = minZ - 1; z <= maxZ + 1; z++) {
for (let y = minY - 1; y <= maxY + 1; y++) {
for (let x = minX - 1; x <= maxX + 1; x++) {
const neighbors = activeNeighbors(space, z, y, x);
const active = get(space, z, y, x);
if (active && neighbors !== 2 && neighbors !== 3) {
set(newSpace, z, y, x, false);
} else if (!active && neighbors === 3) {
set(newSpace, z, y, x, true);
} else {
set(newSpace, z, y, x, active);
}
}
}
}
return newSpace;
}
Insert cell
testInputStep1 = step(parse(testInput))
Insert cell
countActive = space => {
let sum = 0;
space.forEach((ySpace, z) =>
ySpace.forEach((xSpace, y) =>
xSpace.forEach(value => {
if (value) sum++;
})
)
);
return sum;
}
Insert cell
sixCycleCount = input => {
let space = parse( input );
for ( let i = 0; i < 6; i++ ) {
space = step(space);
}
return countActive(space);
}
Insert cell
sixCycleCount(testInput)
Insert cell
Insert cell
Insert cell
sixCycleCount(input)
Insert cell
md`## Part 2`
Insert cell
hyperGet = (space, w, z, y, x) => {
return space.get(w)?.get(z)?.get(y)?.get(x);
}
Insert cell
hyperSet = (space, w, z, y, x, val) => {
let wSpace = space.get(w);
if (! wSpace) {
space.set(w, new Map().set(z, new Map().set(y, new Map().set(x, val))));
return;
}
let zSpace = wSpace.get(z);
if (!zSpace) {
wSpace.set(z, new Map().set(y, new Map().set(x, val)));
return;
}
let ySpace = zSpace.get(y);
if (!ySpace) {
zSpace.set(y, new Map().set(x, val));
return;
}
ySpace.set(x, val);
}
Insert cell
hyperParse = input => {
const space = new Map();
const grid = input.split('\n').map(r => r.split(''));
for (let i = 0; i < grid.length; i++) {
for (let j = 0; j < grid[i].length; j++) {
if (grid[i][j] === '#') hyperSet(space, 0, 0, i, j, true);
}
}
return space;
}
Insert cell
hyperDeltas = {
const out = [];
for (let i = 0; i < 81; i++) {
if (i === 40) continue; // don't want [0,0,0,0]
out.push(
i
.toString(3) // trinary, e.g. 7 = 21
.padStart(4, '0') // left pad 021
.split('') // [ '0', '2', '1' ]
.map(n => parseInt(n) - 1) // [ -1, 1, 0 ]
);
}
return out;
}
Insert cell
hyperactiveNeighbors = (space, w, z, y, x) => {
return hyperDeltas.filter(([deltaW, deltaZ, deltaY, deltaX]) =>
hyperGet(space, w + deltaW, z + deltaZ, y + deltaY, x + deltaX)
).length;
}
Insert cell
hyperspaceRange = space => {
const range = {
minX: Infinity,
minY: Infinity,
minZ: Infinity,
minW: Infinity,
maxX: -Infinity,
maxY: -Infinity,
maxZ: -Infinity,
maxW: -Infinity
};
space.forEach((zSpace, w) => {
if (w < range.minW) range.minW = w;
if (w > range.maxW) range.maxW = w;
zSpace.forEach((ySpace, z) => {
if (z < range.minZ) range.minZ = z;
if (z > range.maxZ) range.maxZ = z;
ySpace.forEach((xSpace, y) => {
if (y < range.minY) range.minY = y;
if (y > range.maxY) range.maxY = y;
xSpace.forEach((val, x) => {
if (x < range.minX) range.minX = x;
if (x > range.maxX) range.maxX = x;
});
});
});
});
return range;
}
Insert cell
hyperStep = space => {
const newSpace = new Map();
const { minX, minY, minZ, minW, maxX, maxY, maxZ, maxW } = hyperspaceRange(
space
);
for (let w = minW - 1; w <= maxW + 1; w++) {
for (let z = minZ - 1; z <= maxZ + 1; z++) {
for (let y = minY - 1; y <= maxY + 1; y++) {
for (let x = minX - 1; x <= maxX + 1; x++) {
const neighbors = hyperactiveNeighbors(space, w, z, y, x);
const active = hyperGet(space, w, z, y, x);
if (active && neighbors !== 2 && neighbors !== 3) {
hyperSet(newSpace, w, z, y, x, false);
} else if (!active && neighbors === 3) {
hyperSet(newSpace, w, z, y, x, true);
} else {
hyperSet(newSpace, w, z, y, x, active);
}
}
}
}
}
return newSpace;
}
Insert cell
hyperStep(hyperParse(testInput))
Insert cell
hyperCountActive = space => {
let sum = 0;
space.forEach((zSpace, w) =>
zSpace.forEach((ySpace, z) =>
ySpace.forEach((xSpace, y) =>
xSpace.forEach(value => {
if (value) sum++;
})
)
)
);
return sum;
}
Insert cell
sixHypercycleCount = input => {
let space = hyperParse( input );
for ( let i = 0; i < 6; i++ ) {
space = hyperStep(space);
}
return hyperCountActive(space);
}
Insert cell
sixHypercycleCount(testInput)
Insert cell
sixHypercycleCount(input)
Insert cell
Type JavaScript, then Shift-Enter. Ctrl-space for more options. Arrow ↑/↓ to switch modes.

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