Public
Edited
Dec 12, 2022
3 stars
Insert cell
Insert cell
Insert cell
Insert cell
path = (paths) => {
let p = d3.greatest(paths.keys(), ([x, y]) => x + y);
const path = [p];
while (path[0][0] !== 0 || path[0][1] !== 0)
path.unshift((p = part1.paths.get(p)));
return path;
}
Insert cell
// // load the notebook faster
// part2 = aStar({
// start: [0, 0],
// isEnd: ([x, y]) => x === dim * 5 - 1 && y === dim * 5 - 1,
// neighbor: (p) => [...neighbors(p, 5)],
// distance: (a, b) => extended(b),
// heuristic: ([x, y]) => dim - x + dim - y,
// hash: JSON.stringify,
// timeout: 10000
// })
Insert cell
extended = ([x, y]) => {
const [tx, ty] = [Math.floor(x / dim), Math.floor(y / dim)];
const [dx, dy] = [x % dim, y % dim];
return wrap(map.get([dx, dy]) + tx + ty);
}
Insert cell
wrap = (n) => {
while (n > 9) n -= 9;
return n;
}
Insert cell
part1.distances.get([dim-1, dim-1])
Insert cell
part1 = {
play;
const frame = Math.floor((dim * dim) / 30);
for (const step of djikstra([dim - 1, dim - 1]))
if (step.seen.size % frame === 0 || step.done) yield step;
}
Insert cell
function* djikstra([ex, ey], m = 1) {
const seen = new d3.InternSet([], JSON.stringify);
const next = new d3.InternSet([], JSON.stringify);
const distances = new d3.InternMap([[[0, 0], 0]], JSON.stringify);
const paths = new d3.InternMap([], JSON.stringify);
let p = [0, 0];
while (p[0] !== ex || p[1] !== ey) {
for (const n of neighbors(p, m)) {
if (seen.has(n)) continue;
const d = distances.get(p) + extended(n);
if (!distances.has(n) || d < distances.get(n)) {
distances.set(n, d);
paths.set(n, p);
}
next.add(n);
}
seen.add(p);
p = d3.least(
d3.filter(next, ([p]) => !seen.has(p)),
(a, b) => distances.get(a) - distances.get(b)
);
next.delete(p);
yield { seen, distances, paths };
}
yield { seen, distances, paths, done: true };
}
Insert cell
Insert cell
{
const t0 = Date.now();
const times = [];
for (const step of djikstra([dim - 1, dim - 1]))
times.push([Date.now() - t0, step.seen.size]);
return Plot.line(times).plot({ x: { label: "ms →" }, y: {label: "↑ seen"} });
}
Insert cell
function* neighbors([x, y], m = 1) {
for (const [dx, dy] of [
[-1, 0],
[1, 0],
[0, -1],
[0, 1]
]) {
const p = [x + dx, y + dy];
if (0 <= p[0] && p[0] < dim * m && 0 <= p[1] && p[1] < dim * m) yield p;
}
}
Insert cell
Insert cell
map = {
const map = new d3.InternMap([], JSON.stringify);
const rows = data.trim().split("\n").map((l) => l.split("").map(Number));
for (let y = 0; y < rows.length; y++)
for (let x = 0; x < rows[y].length; x++)
map.set([x, y], rows[y][x]);
return map;
}
Insert cell
dim = data.trim().split("\n").length
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