Public
Edited
Dec 17, 2023
Insert cell
Insert cell
show(input, energized)
Insert cell
answer1 = [...energized].filter(
(d) => !(d < 0 || d >= W * (W + 1) || (1 + d) % (W + 1) === 0)
).length
Insert cell
W = input.trim().split("\n").length
Insert cell
energized = {
const UP = 1 << 0,
DOWN = 1 << 1,
LEFT = 1 << 2,
RIGHT = 1 << 3;
const V = new Float32Array((W + 1) * (W + 1)).fill(0);

// initialize
const energized = new Set([0]);
V[0] |= RIGHT;

let s;

do {
for (const e of energized) {
if (V[e] & RIGHT) {
switch (input[e]) {
case ".":
case "-":
V[e + 1] |= RIGHT;
energized.add(e + 1);
break;
case "|":
V[e - (W + 1)] |= UP;
V[e + (W + 1)] |= DOWN;
energized.add(e - (W + 1));
energized.add(e + (W + 1));
break;
case "\\":
V[e + (W + 1)] |= DOWN;
energized.add(e + (W + 1));
break;
case "/":
V[e - (W + 1)] |= UP;
energized.add(e - (W + 1));
break;
}
}
if (V[e] & LEFT) {
switch (input[e]) {
case ".":
case "-":
V[e - 1] |= LEFT;
energized.add(e - 1);
break;
case "|":
V[e - (W + 1)] |= UP;
V[e + (W + 1)] |= DOWN;
energized.add(e - (W + 1));
energized.add(e + (W + 1));
break;
case "/":
V[e + (W + 1)] |= DOWN;
energized.add(e + (W + 1));
break;
case "\\":
V[e - (W + 1)] |= UP;
energized.add(e - (W + 1));
break;
}
}
if (V[e] & UP) {
switch (input[e]) {
case ".":
case "|":
V[e - (W + 1)] |= UP;
energized.add(e - (W + 1));
break;
case "-":
V[e - 1] |= LEFT;
V[e + 1] |= RIGHT;
energized.add(e - 1);
energized.add(e + 1);
break;
case "/":
V[e + 1] |= RIGHT;
energized.add(e + 1);
break;
case "\\":
V[e - 1] |= LEFT;
energized.add(e - 1);
break;
}
}
if (V[e] & DOWN) {
switch (input[e]) {
case ".":
case "|":
V[e + (W + 1)] |= DOWN;
energized.add(e + (W + 1));
break;
case "-":
V[e - 1] |= LEFT;
V[e + 1] |= RIGHT;
energized.add(e - 1);
energized.add(e + 1);
break;
case "\\":
V[e + 1] |= RIGHT;
energized.add(e + 1);
break;
case "/":
V[e - 1] |= LEFT;
energized.add(e - 1);
break;
}
}
}
yield energized;
const s0 = d3.sum(V);
if (s0 === s) break;
s = s0;
} while (true);
yield energized;
}
Insert cell
Insert cell
Insert cell
energized2 = {
await visibility();
const UP = 1 << 0,
DOWN = 1 << 1,
LEFT = 1 << 2,
RIGHT = 1 << 3;
const V = new Float32Array((W + 1) * (W + 1));

const COUNTS = [];
const valid = (d) => !(d < 0 || d >= W * (W + 1) || (1 + d) % (W + 1) === 0);

// for the display
mutable best = count(W - 1 + 93 * (W + 1), LEFT);

for (let i = 0; i < W; ++i) {
// TOP
COUNTS.push([...count(i, DOWN)].filter(valid).length);
// LEFT
COUNTS.push([...count(i * (W + 1), RIGHT)].filter(valid).length);
// BOTTOM
COUNTS.push([...count(i + (W - 1) * (W + 1), UP)].filter(valid).length);
// RIGHT
COUNTS.push([...count(W - 1 + i * (W + 1), LEFT)].filter(valid).length);

yield COUNTS;
}

return COUNTS;

function count(i, dir) {
// initialize
V.fill(0);
const energized = new Set([i]);
V[i] |= dir;

let s;

do {
for (const e of energized) {
if (V[e] & RIGHT) {
switch (input[e]) {
case ".":
case "-":
V[e + 1] |= RIGHT;
energized.add(e + 1);
break;
case "|":
V[e - (W + 1)] |= UP;
V[e + (W + 1)] |= DOWN;
energized.add(e - (W + 1));
energized.add(e + (W + 1));
break;
case "\\":
V[e + (W + 1)] |= DOWN;
energized.add(e + (W + 1));
break;
case "/":
V[e - (W + 1)] |= UP;
energized.add(e - (W + 1));
break;
}
}
if (V[e] & LEFT) {
switch (input[e]) {
case ".":
case "-":
V[e - 1] |= LEFT;
energized.add(e - 1);
break;
case "|":
V[e - (W + 1)] |= UP;
V[e + (W + 1)] |= DOWN;
energized.add(e - (W + 1));
energized.add(e + (W + 1));
break;
case "/":
V[e + (W + 1)] |= DOWN;
energized.add(e + (W + 1));
break;
case "\\":
V[e - (W + 1)] |= UP;
energized.add(e - (W + 1));
break;
}
}
if (V[e] & UP) {
switch (input[e]) {
case ".":
case "|":
V[e - (W + 1)] |= UP;
energized.add(e - (W + 1));
break;
case "-":
V[e - 1] |= LEFT;
V[e + 1] |= RIGHT;
energized.add(e - 1);
energized.add(e + 1);
break;
case "/":
V[e + 1] |= RIGHT;
energized.add(e + 1);
break;
case "\\":
V[e - 1] |= LEFT;
energized.add(e - 1);
break;
}
}
if (V[e] & DOWN) {
switch (input[e]) {
case ".":
case "|":
V[e + (W + 1)] |= DOWN;
energized.add(e + (W + 1));
break;
case "-":
V[e - 1] |= LEFT;
V[e + 1] |= RIGHT;
energized.add(e - 1);
energized.add(e + 1);
break;
case "\\":
V[e + 1] |= RIGHT;
energized.add(e + 1);
break;
case "/":
V[e - 1] |= LEFT;
energized.add(e - 1);
break;
}
}
}
const s0 = d3.sum(V);
if (s0 === s) break;
s = s0;
} while (true);

return energized;
}
}
Insert cell
l = d3.maxIndex(energized2)
Insert cell
answer2 = energized2[l]
Insert cell
Insert cell
m = l % 4 // RIGHT
Insert cell
i = Math.floor(l / 4)
Insert cell
mutable best = null
Insert cell
input = FileAttachment("input.txt").text() // beware of escaping \
Insert cell
sample = `.|...\\....
|.-.\\.....
.....|-...
........|.
..........
.........\\
..../.\\\\..
.-.-/..|..
.|....-|.\\
..//.|....
`
Insert cell
show = (txt, energized, startRight) =>
html`<pre style="font-size:9px; line-height: 5px; color: ${
energized ? "#ddd" : "#000"
}">${Array.from(txt, (d, i) => {
const a = (i + 1) % (W + 1) === 0 ? "◼\n" : d;
return i === startRight * (W + 1) + W
? html`<span style="color: red">${a}</span>`
: energized?.has(i)
? html`<span style="color: #333">${a}</span>`
: a;
})}</pre>`
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