main.js 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. const fs = require('fs');
  2. const readline = require('readline');
  3. function computeScore(pos, target, map) {
  4. }
  5. function taxicab(src, target) {
  6. return Math.abs(src[0] - target[0]) + Math.abs(src[1] - target[1]);
  7. }
  8. let seen = {};
  9. function pushPossibility(arr, currentPos, pos, target, map) {
  10. if (pos[0] < 0 || pos[1] < 0 || pos[0] >= map[0].length || pos[1] >= map.length || map[pos[1]][pos[0]] - map[currentPos.pos[1]][currentPos.pos[0]] > 1 || arr.find(i => i.pos[0] === pos[0] && i.pos[1] === pos[1]) || seen[pos[0]+'x'+pos[1]])
  11. return;
  12. let elevScore = map[target[1]][target[0]] - map[pos[1]][pos[0]]
  13. seen[pos[0]+'x'+pos[1]] = true;
  14. arr.push({ pos: pos, elevScore: elevScore, score: elevScore + taxicab(pos, target) + currentPos.score, history: currentPos });
  15. }
  16. function pushPossibilities(arr, target, map) {
  17. let pos = arr.shift();
  18. pushPossibility(arr, pos, [pos.pos[0]+1, pos.pos[1]], target, map);
  19. pushPossibility(arr, pos, [pos.pos[0]-1, pos.pos[1]], target, map);
  20. pushPossibility(arr, pos, [pos.pos[0], pos.pos[1]+1], target, map);
  21. pushPossibility(arr, pos, [pos.pos[0], pos.pos[1]-1], target, map);
  22. return arr.sort((a, b) => a.score - b.score);
  23. }
  24. function backtrack(item) {
  25. let result = [];
  26. while (item) {
  27. result.push(item.pos);
  28. item = item.history;
  29. }
  30. return result.reverse();
  31. }
  32. function AStar(pos, target, map) {
  33. let possibilities = [ { pos: pos, score: taxicab(pos, target), elevScore: 0 } ];
  34. seen = {};
  35. let output = null;
  36. do {
  37. possibilities = pushPossibilities(possibilities, target, map);
  38. output = possibilities.filter(i => i.pos[0] === target[0] && i.pos[1] === target[1]);
  39. } while (possibilities.length && !output.length);
  40. return backtrack(output[0]).length -1;
  41. }
  42. async function main() {
  43. let map = [];
  44. let currentPos = [];
  45. let target = [];
  46. let lineIndex = 0;
  47. for await (let line of readline.createInterface({ input: process.stdin })) {
  48. map.push(line.split('').map((i, pos) => {
  49. if (i === 'S') { currentPos = [ pos, lineIndex ]; i = 'a'; }
  50. if (i === 'E') { target = [ pos, lineIndex ]; i = 'z'; }
  51. return i.charCodeAt(0) - 'a'.charCodeAt(0);}));
  52. ++lineIndex;
  53. }
  54. console.log("Step 1: ", AStar(currentPos, target, map));
  55. let minSteps = Infinity;
  56. for (let i =0; i < map.length; ++i)
  57. for (let j =0; j < map.length; ++j)
  58. if (map[i][j] === 0) {
  59. let steps = AStar([j, i], target, map);
  60. if (steps > 0)
  61. minSteps = Math.min(minSteps, steps);
  62. }
  63. console.log("Step 2: ", minSteps);
  64. };
  65. (main());