Public
Edited
Dec 16, 2023
Insert cell
Insert cell
Insert cell
function parse(input) {
return input.split("\n").map((row) => row.split(""));
}
Insert cell
Insert cell
function rotate(dir, symbol) {
if (symbol === "╱") {
return [-dir[1], -dir[0]]; // Mirror rotates beam 90 degrees
}
if (symbol === "╲") {
return [dir[1], dir[0]]; // Mirror rotates beam anticlockwise 90 degrees
}
return dir;
}
Insert cell
Insert cell
function energised(mirrors, start = { r: 0, c: 0, dir: [0, 1] }) {
const grid = AOC.gMap(() => 0, mirrors);
const [nRows, nCols] = [grid.length, grid[0].length];
const history = new Set();
const beams = [start];
grid[start.r][start.c] = 1;

while (beams.length > 0) {
const b = beams.shift();
const hash =
b.r * nCols * 9 + b.c * 9 + (b.dir[0] + 1) + (b.dir[1] + 1) * 3;
if (!history.has(hash)) {
history.add(hash);
const mirror = mirrors[b.r][b.c];
b.dir = rotate(b.dir, mirror);
if (mirror === "-" && b.dir[0] !== 0) {
beams.push({ r: b.r, c: b.c, dir: [0, -1] });
b.dir = [0, 1];
} else if (mirror === "|" && b.dir[1] !== 0) {
beams.push({ r: b.r, c: b.c, dir: [1, 0] });
b.dir = [-1, 0];
}

const [r, c] = [b.r + b.dir[0], b.c + b.dir[1]];
if (r >= 0 && c >= 0 && r < nRows && c < nCols) {
grid[r][c] = 1;
beams.push({ r: r, c: c, dir: b.dir });
}
}
}
return AOC.sum(grid.flat());
}
Insert cell
function part1(input) {
return energised(parse(puzzleInput));
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function maxEnergised(mirrors) {
const [nRows, nCols] = [mirrors.length, mirrors[0].length];
let maxE = 0;

for (let r = 0; r < nRows; r++) {
maxE = Math.max(
maxE,
energised(mirrors, { r: r, c: 0, dir: [0, 1] }),
energised(mirrors, { r: r, c: nCols - 1, dir: [0, -1] })
);
}

for (let c = 1; c < nCols - 1; c++) {
maxE = Math.max(
maxE,
energised(mirrors, { r: 0, c: c, dir: [1, 0] }),
energised(mirrors, { r: nRows - 1, c: c, dir: [-1, 0] })
);
}
return maxE;
}
Insert cell
function part2(input) {
return maxEnergised(parse(input));
}
Insert cell
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