15_1.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. const fs = require("node:fs");
  2. const Computer = require("../IntComp/Computer");
  3. /* Set up the computer */
  4. const input = fs.readFileSync("./15/input.dat", "utf8")
  5. .split(",")
  6. .map((x) => parseInt(x, 10));
  7. const droid = new Computer(input);
  8. /* Set up values for the simulation */
  9. /**
  10. * Directions the droid can move in
  11. */
  12. const Directions = {
  13. NORTH: 1,
  14. SOUTH: 2,
  15. EAST: 3,
  16. WEST: 4,
  17. };
  18. /**
  19. * Vectorized values for the Directions values
  20. */
  21. const Vectors = {
  22. NORTH: 1,
  23. SOUTH: -1,
  24. EAST: 1,
  25. WEST: -1,
  26. };
  27. /**
  28. * Tile data for rendering the droid's internal map
  29. */
  30. const mapTiles = {
  31. WALL: "█",
  32. EMPTY: ".",
  33. OXYGEN: "0",
  34. };
  35. /**
  36. * The current position of the droid
  37. *
  38. * X and Y are relative to the droid's position at the start of the
  39. * simulation.
  40. */
  41. const droidPosition = {
  42. x: 0,
  43. y: 0
  44. };
  45. const droidMap = new Map();
  46. /**
  47. * Statuses output but the droid
  48. */
  49. const STATUS = ["NO_MOVEMENT", "MOVEMENT_SUCCESSFUL", "OXYGEN_FOUND"];
  50. /**
  51. * The last direction we had the droid move in
  52. */
  53. let lastDirection = Directions.EAST;
  54. /**
  55. * The last status code output by the droid
  56. */
  57. let lastSignal = -1;
  58. let mapLooped = false;
  59. // Start the droid
  60. droid.Run()
  61. // Continue running of droid
  62. do {
  63. // Handle input to the droid
  64. if (droid.awaitingInput) {
  65. // Get the new direction to move in
  66. let currDirection = updateMap(lastDirection, lastSignal);
  67. droid.Input(currDirection);
  68. lastDirection = currDirection;
  69. }
  70. // Handle the droid's output
  71. if (droid.HasOutput()) {
  72. lastSignal = droid.outputValues.pop()
  73. console.log(STATUS[lastSignal]);
  74. }
  75. } while (droid.running && !mapLooped);
  76. /**
  77. * Update the map data and return a new dirction to move in
  78. *
  79. * @param {1|2|3|4} lastDirection The last direction the droid moved in
  80. * @param {0|1|2} lastSignal The last signal output by the droid
  81. *
  82. * @returns {1|2|3|4} A new direction for the droid to move in
  83. */
  84. function updateMap(lastDirection, lastSignal) {
  85. let newDirection = lastDirection;
  86. let mapX = droidPosition.x;
  87. let mapY = droidPosition.y;
  88. let foundTile = mapTiles.EMPTY;
  89. if (lastSignal == 0) {
  90. if (lastDirection == Directions.EAST) {
  91. mapX += Vectors.EAST;
  92. newDirection = Directions.NORTH;
  93. }
  94. else if (lastDirection == Directions.NORTH) {
  95. mapY += Vectors.NORTH;
  96. newDirection = Directions.WEST;
  97. }
  98. else if (lastDirection == Directions.WEST) {
  99. mapX += Vectors.WEST;
  100. newDirection = Directions.SOUTH;
  101. }
  102. else if (lastDirection == Directions.SOUTH) {
  103. mapY += Vectors.SOUTH;
  104. newDirection = Directions.EAST;
  105. }
  106. foundTile = mapTiles.WALL;
  107. }
  108. else if (lastSignal == 1) {
  109. if (lastDirection == Directions.EAST) {
  110. droidPosition.x += Vectors.EAST;
  111. }
  112. else if (lastDirection == Directions.NORTH) {
  113. droidPosition.y += Vectors.NORTH;
  114. }
  115. else if (lastDirection == Directions.WEST) {
  116. droidPosition.x += Vectors.WEST;
  117. }
  118. else if (lastDirection == Directions.SOUTH) {
  119. droidPosition.y += Vectors.SOUTH;
  120. }
  121. foundTile = mapTiles.EMPTY;
  122. }
  123. else if (lastSignal == 2) {
  124. foundTile = mapTiles.OXYGEN;
  125. console.log(STATUS[lastSignal]);
  126. }
  127. mapLooped = droidMap.has(`${mapX},${mapY}`) && mapX + mapY != 0;
  128. droidMap.set(`${mapX},${mapY}`, foundTile);
  129. return newDirection;
  130. }