Published
Edited
Dec 28, 2018
Insert cell
Insert cell
Insert cell
function countNeighbors (idx, grid) {
let counts = { '#': 0, '.': 0, '|': 0 };
let neighborhood = [];
let col = idx % SIZE;
let row = (idx - col) / SIZE;
let minRow = Math.max(0, row - 1);
let maxRow = Math.min(SIZE, row + 2);
let minCol = Math.max(0, col - 1);
let maxCol = Math.min(SIZE, col + 2);

for (let i = minRow; i < maxRow; i++) {
for (let j = minCol; j < maxCol; j++) {
let nidx = j + i * SIZE;
counts[grid[nidx]]++;
neighborhood.push(nidx);
}
}
return [counts, neighborhood];
}
Insert cell
function gridValue (grid) {
let out = {'#': 0, '.': 0, '|': 0};
for (let char of grid) {
out[char]++;
}
return out['#'] * out['|'];
}
Insert cell
function *tick () {
let grid = INPUT.split('\n').map(row => row.split('')).flat();
let newGrid = [...grid];
let changes = new Set(Array(SIZE**2).keys());
while (true) {
grid = [...newGrid];
let newChanges = [];
// Loop only over cells that changed or are adjacent to one that did
for (let idx of changes) {
let [counts, neighborhood] = countNeighbors(idx, grid);
if (grid[idx] === '.') {
if (counts['|'] > 2) {
newGrid[idx] = '|';
newChanges.push(...neighborhood);
}
} else if (grid[idx] === '|') {
if (counts['#'] > 2) {
newGrid[idx] = '#';
newChanges.push(...neighborhood);
}
} else if (grid[idx] === '#') {
if (counts['#'] < 2 || counts['|'] === 0) {
newGrid[idx] = '.';
newChanges.push(...neighborhood);
}
}
}
changes = new Set(newChanges);
yield newGrid;
}
}
Insert cell
part1 = {
let game = tick();
let grid;
for (let i = 0; i < 10; i++) {
grid = game.next().value;
}
return gridValue(grid);
}
Insert cell
Insert cell
part2 = {
let game = tick();
let grid;

let t = 0;
let pattern;
let lastSeen = {};

while (true) {
grid = game.next().value;
pattern = grid.join('');
if (lastSeen[pattern]) {
break;
}
lastSeen[pattern] = t;
t++;
}

let repeatPeriod = t - lastSeen[pattern];
let iterationsLeft = (1000000000 - t - 1) % repeatPeriod;

for (let i = 0; i < iterationsLeft; i++) {
grid = game.next().value;
}

return gridValue(grid);
}
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