function part2(grid) {
for (const { point, x, y } of grid) {
for (const { dx, dy } of dirs) {
let x2 = x + dx;
let y2 = y + dy;
if (grid.at([x2, y2])?.height >= point.height - 1) {
point.neighbors.push([x2, y2]);
}
}
}
const visited = new Set();
let tentativeDistances = new Map();
let unvisited = Array.from(grid);
let end = unvisited.find((d) => d.point.end);
let endAddress = `${end.x},${end.y}`;
tentativeDistances.set(endAddress, 0);
while (unvisited.length) {
let currentIndex = d3.minIndex(
unvisited,
(d) => tentativeDistances.get(`${d.x},${d.y}`) ?? Infinity
);
let [current] = unvisited.splice(currentIndex, 1);
let currentAddress = `${current.x},${current.y}`;
let currentDist = tentativeDistances.get(currentAddress);
for (const neighbor of current.point.neighbors) {
let ps = neighbor.join(",");
if (visited.has(ps)) continue;
if ((tentativeDistances.get(ps) ?? Infinity) > currentDist + 1) {
tentativeDistances.set(ps, currentDist + 1);
}
}
visited.add(currentAddress);
}
let combined = Array.from(
tentativeDistances.entries(),
([address, distance]) => ({
pos: address.split(",").map((d) => +d),
distance
})
)
.map((d) => ({
...d,
height: grid.at(d.pos).height
}))
.filter((d) => d.height === 0);
return d3.min(combined, (d) => d.distance);
}