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"]);
|
|
|
|
|