const fs = require("node:fs"); const Computer = require("../IntComp/Computer"); /* Set up the computer */ const input = fs.readFileSync("./15/input.dat", "utf8") .split(",") .map((x) => parseInt(x, 10)); const droid = new Computer(input); /* Set up values for the simulation */ /** * Directions the droid can move in */ const Directions = { NORTH: 1, SOUTH: 2, EAST: 3, WEST: 4, }; /** * Vectorized values for the Directions values */ const Vectors = { NORTH: 1, SOUTH: -1, EAST: 1, WEST: -1, }; /** * Tile data for rendering the droid's internal map */ const mapTiles = { WALL: "█", EMPTY: ".", OXYGEN: "0", }; /** * The current position of the droid * * X and Y are relative to the droid's position at the start of the * simulation. */ const droidPosition = { x: 0, y: 0 }; const droidMap = new Map(); /** * Statuses output but the droid */ const STATUS = ["NO_MOVEMENT", "MOVEMENT_SUCCESSFUL", "OXYGEN_FOUND"]; /** * The last direction we had the droid move in */ let lastDirection = Directions.EAST; /** * The last status code output by the droid */ let lastSignal = -1; let mapLooped = false; // Start the droid droid.Run() // Continue running of droid do { // Handle input to the droid if (droid.awaitingInput) { // Get the new direction to move in let currDirection = updateMap(lastDirection, lastSignal); droid.Input(currDirection); lastDirection = currDirection; } // Handle the droid's output if (droid.HasOutput()) { lastSignal = droid.outputValues.pop() console.log(STATUS[lastSignal]); } } while (droid.running && !mapLooped); /** * Update the map data and return a new dirction to move in * * @param {1|2|3|4} lastDirection The last direction the droid moved in * @param {0|1|2} lastSignal The last signal output by the droid * * @returns {1|2|3|4} A new direction for the droid to move in */ function updateMap(lastDirection, lastSignal) { let newDirection = lastDirection; let mapX = droidPosition.x; let mapY = droidPosition.y; let foundTile = mapTiles.EMPTY; if (lastSignal == 0) { if (lastDirection == Directions.EAST) { mapX += Vectors.EAST; newDirection = Directions.NORTH; } else if (lastDirection == Directions.NORTH) { mapY += Vectors.NORTH; newDirection = Directions.WEST; } else if (lastDirection == Directions.WEST) { mapX += Vectors.WEST; newDirection = Directions.SOUTH; } else if (lastDirection == Directions.SOUTH) { mapY += Vectors.SOUTH; newDirection = Directions.EAST; } foundTile = mapTiles.WALL; } else if (lastSignal == 1) { if (lastDirection == Directions.EAST) { droidPosition.x += Vectors.EAST; } else if (lastDirection == Directions.NORTH) { droidPosition.y += Vectors.NORTH; } else if (lastDirection == Directions.WEST) { droidPosition.x += Vectors.WEST; } else if (lastDirection == Directions.SOUTH) { droidPosition.y += Vectors.SOUTH; } foundTile = mapTiles.EMPTY; } else if (lastSignal == 2) { foundTile = mapTiles.OXYGEN; console.log(STATUS[lastSignal]); } mapLooped = droidMap.has(`${mapX},${mapY}`) && mapX + mapY != 0; droidMap.set(`${mapX},${mapY}`, foundTile); return newDirection; }