adventofcode2022/day12/solution.ts

123 lines
3.3 KiB
TypeScript
Raw Normal View History

2022-12-11 23:51:59 -05:00
import { readFileSync } from 'fs';
import { join } from 'path';
const fileString = readFileSync(join(__dirname, "input"), 'utf-8');
var rows = fileString.split("\n");
rows = rows.map(val => {
return val.trim();
});
2022-12-17 00:54:58 -05:00
2022-12-11 23:51:59 -05:00
rows = rows.filter(val => {
return val.length > 0;
});
2022-12-17 00:54:58 -05:00
const grid = rows.map(val => {
return val.split("");
})
var targetPos = [0,0];
for (var i = 0; i < grid.length; i++) {
for (var j = 0; j < grid[i].length; j++) {
if (grid[i][j] == "E") {
console.log("target set", i, j);
targetPos = [i, j];
grid[i][j] = "z";
}
if (grid[i][j] == "S") {
grid[i][j] = "a";
}
}
}
// Build Graph
var graph: {} = {};
for (var i = 0; i < grid.length; i++) {
for (var j = 0; j < grid[i].length; j++) {
const idx = JSON.stringify([i, j])
const height = grid[i][j].charCodeAt(0);
graph[idx] = {
"value": height,
"next": {}
};
if (!((i - 1) < 0)) {
if ((grid[i - 1][j].charCodeAt(0) - height <= 1) && (grid[i - 1][j].charCodeAt(0) - height >= -1)) {
const nidx = JSON.stringify([i - 1, j])
graph[idx]["next"][nidx] = 1;
}
}
if (!((i + 1) >= grid.length)) {
if ((grid[i + 1][j].charCodeAt(0) - height <= 1) && (grid[i + 1][j].charCodeAt(0) - height >= -1)) {
const nidx = JSON.stringify([i + 1, j])
graph[idx]["next"][nidx] = 1;
}
}
if (!((j - 1) < 0)) {
if ((grid[i][j - 1].charCodeAt(0) - height <= 1) && (grid[i][j - 1].charCodeAt(0) - height >= -1)) {
const nidx = JSON.stringify([i, j - 1])
graph[idx]["next"][nidx] = 1;
}
}
if (!((j + 1) >= grid[i].length)) {
if ((grid[i][j + 1].charCodeAt(0) - height <= 1) && (grid[i][j + 1].charCodeAt(0) - height >= -1)) {
const nidx = JSON.stringify([i, j + 1])
graph[idx]["next"][nidx] = 1;
}
}
}
}
function closestNode(distances: {}, visited) {
var shortest = null;
for (const node in distances) {
var curentShortest = shortest === null || distances[node] < distances[shortest];
if (curentShortest && !visited.includes(node)) {
shortest = node;
}
}
return shortest;
}
function findShortestPath(g:{}, startN: string, endN: string) {
var distances = {};
distances[endN] = Infinity;
distances = Object.assign(distances, g[startN]["next"]);
var parents = {endN: null};
for (const neighbor in g[startN]["next"]) {
parents[neighbor] = startN;
}
var visited = [];
var node = closestNode(distances, visited);
while (node) {
var distance = distances[node];
var children = g[node]["next"];
for (const child in children) {
if (child === startN) {
continue;
} else {
var newDistance = distance + children[child];
if (!distances[child] || distances[child] > newDistance) {
distances[child] = newDistance;
parents[child] = node;
}
}
}
visited.push(node);
node = closestNode(distances, visited);
}
var shortestPath = [endN];
var parent = parents[endN];
while (parent) {
shortestPath.push(parent);
parent = parents[parent];
}
shortestPath.reverse();
return {d: distances[endN], s: shortestPath, dd: distances}
}
const res = findShortestPath(graph, JSON.stringify([0,0]), JSON.stringify(targetPos))
console.log(res["dd"], res["d"]);