|
|
|
@ -27,6 +27,17 @@ export const findStart = (topoMap) => {
@@ -27,6 +27,17 @@ export const findStart = (topoMap) => {
|
|
|
|
|
return V(x,y); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
export const findEnd = (topoMap) => { |
|
|
|
|
let y; |
|
|
|
|
let x = R.findIndex(topoMap, (row) => { |
|
|
|
|
let z = row.indexOf("{"); |
|
|
|
|
if (z === -1) return false; |
|
|
|
|
y = z; |
|
|
|
|
return true; |
|
|
|
|
}); |
|
|
|
|
return V(x,y); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
const directions = [ [0,1], [0,-1],[1,0],[-1,0] ].map( |
|
|
|
|
d => V(...d) |
|
|
|
|
); |
|
|
|
@ -42,52 +53,42 @@ const isReachable = (topoMap,pos) => {
@@ -42,52 +53,42 @@ const isReachable = (topoMap,pos) => {
|
|
|
|
|
const baseline = topoMap[pos.x][pos.y].charCodeAt(0); |
|
|
|
|
|
|
|
|
|
return (next) => { |
|
|
|
|
return [0,1].includes( |
|
|
|
|
topoMap[next.x][next.y].charCodeAt(0) - baseline |
|
|
|
|
) |
|
|
|
|
return topoMap[next.x][next.y].charCodeAt(0) - baseline <= 1; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function findShortestPath(topoMap) { |
|
|
|
|
|
|
|
|
|
const initial = findStart(topoMap); |
|
|
|
|
initial.steps = 0; |
|
|
|
|
initial.beenThere = []; |
|
|
|
|
const final = findEnd(topoMap); |
|
|
|
|
|
|
|
|
|
const potentials = [ initial ]; |
|
|
|
|
|
|
|
|
|
let bestSoFar; |
|
|
|
|
const beenThere = topoMap.map( |
|
|
|
|
line => line.map( () => 9999 ) |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
const oom = outOfMap(topoMap.length,topoMap[0].length ); |
|
|
|
|
|
|
|
|
|
let failsafe = 100000; |
|
|
|
|
let failsafe = 10; //topoMap.length*topoMap[0].length ;
|
|
|
|
|
while( potentials.length > 0 ) { |
|
|
|
|
// if(! failsafe--) return;
|
|
|
|
|
const pos = potentials.pop(); // depth-first
|
|
|
|
|
//console.log(pos.steps, bestSoFar);
|
|
|
|
|
|
|
|
|
|
if( bestSoFar && (bestSoFar <= pos.steps) ) continue; |
|
|
|
|
// if(! failsafe--) return;
|
|
|
|
|
const pos = potentials.shift(); // depth-first
|
|
|
|
|
|
|
|
|
|
if( topoMap[pos.x][pos.y] === '{' ) { |
|
|
|
|
bestSoFar = pos.steps; |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
if( beenThere[pos.x][pos.y] <= pos.steps ) continue; |
|
|
|
|
beenThere[pos.x][pos.y] = pos.steps; |
|
|
|
|
|
|
|
|
|
const next = directions.map( |
|
|
|
|
d => d.clone().add(pos) |
|
|
|
|
).filter( R.isNot(oom )) |
|
|
|
|
.filter( isReachable(topoMap,pos) ) |
|
|
|
|
.filter( next => !pos.beenThere.includes( next.toArray().join(',') ) ); |
|
|
|
|
.filter( isReachable(topoMap,pos) ); |
|
|
|
|
|
|
|
|
|
next.forEach( n => n.steps = pos.steps + 1 ); |
|
|
|
|
next.forEach( n => n.beenThere = [ |
|
|
|
|
...pos.beenThere, pos.toArray().join(',') |
|
|
|
|
] ); |
|
|
|
|
|
|
|
|
|
potentials.push(...next); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return bestSoFar; |
|
|
|
|
return beenThere[final.x][final.y]; |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|