Files
AdventOfCode/2022/12.js
2022-12-12 11:57:23 +00:00

72 lines
2.4 KiB
JavaScript

const fs = require('fs');
const map = fs.readFileSync('12.input').toString().split('\n').map(s => s.split(''));
const [rows, cols] = [map.length, map[0].length - 1];
const traverseDirections = [[-1, 0], [1, 0], [0, -1], [0, 1]];
const isInMap = ([row, col]) => row >= 0 && row < rows && col >= 0 && col < cols ;
const bfsCost = currElevation => ([row, col]) => map[row][col].charCodeAt(0) - currElevation.charCodeAt(0) <= 1;
const BreadthFirst = (start, end) => {
const viewQueue = [[start, 0]];
const visited = new Set([JSON.stringify(start)]);
let result = Infinity;
while (viewQueue.length != 0) {
const [pos, views] = viewQueue.shift();
if (JSON.stringify(pos) == JSON.stringify(end)) {
result = views;
break;
}
// Map, so make new array for each up & right direction
traverseDirections.map(([up, right]) => [pos[0] + up, pos[1] + right])
// Can we actually move there?
.filter(isInMap)
// Can we climb there?
.filter(bfsCost(map[pos[0]][pos[1]]))
// Have we seen this before?
.filter(pos => !visited.has(JSON.stringify(pos)))
// OK, add next in direction to view queue
.forEach(pos => {
visited.add(JSON.stringify(pos));
viewQueue.push([pos, views + 1]);
});
}
return result;
}
const partOne = () => {
let start, end;
for (let row = 0; row < rows; row++)
for (let col = 0; col < cols; col++) {
if (map[row][col] == 'S') { start = [row, col]; map[row][col] = "a"; }
if (map[row][col] == 'E') { end = [row, col]; map[row][col] = "z"; }
}
const ret = BreadthFirst(start, end);
map[end[0]][end[1]] = 'E';
return ret;
}
const partTwo = () => {
const starting = [];
let end;
for (let row = 0; row < rows; row++)
for (let col = 0; col < cols; col++) {
if (map[row][col] == 'a') { starting.push([row, col]) }
if (map[row][col] == 'E') { end = [row, col]; map[row][col] = "z"; }
}
const candidates = [];
for (const start of starting)
candidates.push(BreadthFirst(start, end));
return candidates.sort((a, b) => a - b)[0];
}
console.log(`Part 1: ${partOne()}`);
console.log(`Part 2: ${partTwo()}`);