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(); }); rows = rows.filter(val => { return val.length > 0; }); 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"]);