function distToEnd(terrain, endFn) {
const dists = AOC.gInit(terrain.nRows, terrain.nCols, dMax);
const [rEnd, cEnd] = terrain.end;
dists[rEnd][cEnd] = 0;
const todo = [[...terrain.end, 0]];
const traverse = (todo) => {
while (todo.length > 0) {
const [r0, c0, dist] = todo.shift();
if (endFn(r0, c0, terrain)) {
return dists[r0][c0];
}
canVisit(r0, c0, terrain).forEach(([r, c]) => {
if (dists[r][c] === dMax) {
dists[r][c] = dist + 1;
todo.push([r, c, dist + 1]);
}
});
}
};
return traverse(todo);
}