adventofcode/2022/12/part1.js

95 lines
2.3 KiB
JavaScript

import * as R from "remeda";
import Victor from "@a-robu/victor";
import { readFile } from "../05/part1.js";
const V = (x,y) => new Victor(x,y);
const readInput = (...args) =>
R.pipe(
readFile(...args),
(lines) => lines.split("\n"),
R.compact, // remove last line
R.map((line) => line.split("").map( c => c ==='S' ? '`' : c === 'E' ? '{' : c ))
);
export const puzzleInput = readInput(import.meta.url, "input");
export const sample = readInput(import.meta.url, "sample");
export const findStart = (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)
);
const outOfMap = (maxX,maxY) => (loc) => {
if( Math.min( loc.x, loc.y ) < 0 ) return true;
if( loc.x >= maxX ) return true;
if( loc.y >= maxY ) return true;
return false;
}
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
)
}
}
function findShortestPath(topoMap) {
const initial = findStart(topoMap);
initial.steps = 0;
initial.beenThere = [];
const potentials = [ initial ];
let bestSoFar;
const oom = outOfMap(topoMap.length,topoMap[0].length );
let failsafe = 100000;
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( topoMap[pos.x][pos.y] === '{' ) {
bestSoFar = pos.steps;
continue;
}
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(',') ) );
next.forEach( n => n.steps = pos.steps + 1 );
next.forEach( n => n.beenThere = [
...pos.beenThere, pos.toArray().join(',')
] );
potentials.push(...next);
}
return bestSoFar;
}
export default findShortestPath;