123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- const util = require("util");
- const Computer = require("../IntComp/Computer");
- const SpaceImageFormat = require("../SpaceImageFormat/SpaceImageFormat");
- const input = [3, 8, 1005, 8, 330, 1106, 0, 11, 0, 0, 0, 104, 1, 104, 0, 3, 8, 102, -1, 8, 10, 101, 1, 10, 10, 4, 10, 1008, 8, 0, 10, 4, 10, 102, 1, 8, 29, 3, 8, 1002, 8, -1, 10, 1001, 10, 1, 10, 4, 10, 1008, 8, 0, 10, 4, 10, 101, 0, 8, 51, 1, 1103, 2, 10, 1006, 0, 94, 1006, 0, 11, 1, 1106, 13, 10, 3, 8, 1002, 8, -1, 10, 101, 1, 10, 10, 4, 10, 1008, 8, 1, 10, 4, 10, 1001, 8, 0, 87, 3, 8, 102, -1, 8, 10, 101, 1, 10, 10, 4, 10, 1008, 8, 0, 10, 4, 10, 1001, 8, 0, 109, 2, 1105, 5, 10, 2, 103, 16, 10, 1, 1103, 12, 10, 2, 105, 2, 10, 3, 8, 102, -1, 8, 10, 1001, 10, 1, 10, 4, 10, 108, 1, 8, 10, 4, 10, 1001, 8, 0, 146, 1006, 0, 49, 2, 1, 12, 10, 2, 1006, 6, 10, 1, 1101, 4, 10, 3, 8, 1002, 8, -1, 10, 1001, 10, 1, 10, 4, 10, 108, 0, 8, 10, 4, 10, 1001, 8, 0, 183, 1, 6, 9, 10, 1006, 0, 32, 3, 8, 102, -1, 8, 10, 1001, 10, 1, 10, 4, 10, 1008, 8, 1, 10, 4, 10, 101, 0, 8, 213, 2, 1101, 9, 10, 3, 8, 1002, 8, -1, 10, 1001, 10, 1, 10, 4, 10, 1008, 8, 1, 10, 4, 10, 101, 0, 8, 239, 1006, 0, 47, 1006, 0, 4, 2, 6, 0, 10, 1006, 0, 58, 3, 8, 1002, 8, -1, 10, 1001, 10, 1, 10, 4, 10, 1008, 8, 0, 10, 4, 10, 102, 1, 8, 274, 2, 1005, 14, 10, 1006, 0, 17, 1, 104, 20, 10, 1006, 0, 28, 3, 8, 102, -1, 8, 10, 1001, 10, 1, 10, 4, 10, 108, 1, 8, 10, 4, 10, 1002, 8, 1, 309, 101, 1, 9, 9, 1007, 9, 928, 10, 1005, 10, 15, 99, 109, 652, 104, 0, 104, 1, 21101, 0, 937263411860, 1, 21102, 347, 1, 0, 1105, 1, 451, 21101, 932440724376, 0, 1, 21102, 1, 358, 0, 1105, 1, 451, 3, 10, 104, 0, 104, 1, 3, 10, 104, 0, 104, 0, 3, 10, 104, 0, 104, 1, 3, 10, 104, 0, 104, 1, 3, 10, 104, 0, 104, 0, 3, 10, 104, 0, 104, 1, 21101, 0, 29015167015, 1, 21101, 0, 405, 0, 1106, 0, 451, 21102, 1, 3422723163, 1, 21101, 0, 416, 0, 1106, 0, 451, 3, 10, 104, 0, 104, 0, 3, 10, 104, 0, 104, 0, 21101, 0, 868389376360, 1, 21101, 0, 439, 0, 1105, 1, 451, 21102, 825544712960, 1, 1, 21102, 1, 450, 0, 1106, 0, 451, 99, 109, 2, 21201, -1, 0, 1, 21101, 0, 40, 2, 21102, 482, 1, 3, 21102, 1, 472, 0, 1106, 0, 515, 109, -2, 2106, 0, 0, 0, 1, 0, 0, 1, 109, 2, 3, 10, 204, -1, 1001, 477, 478, 493, 4, 0, 1001, 477, 1, 477, 108, 4, 477, 10, 1006, 10, 509, 1101, 0, 0, 477, 109, -2, 2106, 0, 0, 0, 109, 4, 2101, 0, -1, 514, 1207, -3, 0, 10, 1006, 10, 532, 21102, 1, 0, -3, 22101, 0, -3, 1, 22102, 1, -2, 2, 21102, 1, 1, 3, 21101, 551, 0, 0, 1106, 0, 556, 109, -4, 2105, 1, 0, 109, 5, 1207, -3, 1, 10, 1006, 10, 579, 2207, -4, -2, 10, 1006, 10, 579, 22102, 1, -4, -4, 1106, 0, 647, 21201, -4, 0, 1, 21201, -3, -1, 2, 21202, -2, 2, 3, 21102, 1, 598, 0, 1106, 0, 556, 22101, 0, 1, -4, 21101, 1, 0, -1, 2207, -4, -2, 10, 1006, 10, 617, 21102, 0, 1, -1, 22202, -2, -1, -2, 2107, 0, -3, 10, 1006, 10, 639, 21201, -1, 0, 1, 21102, 639, 1, 0, 105, 1, 514, 21202, -2, -1, -2, 22201, -4, -2, -4, 109, -5, 2105, 1, 0];
- /** All possible vectors for the robot to move */
- const Vectors = {
- NORTH: {
- x: 0,
- y: -1,
- },
- SOUTH: {
- x: 0,
- y: 1,
- },
- EAST: {
- x: 1,
- y: 0,
- },
- WEST: {
- x: -1,
- y: 0,
- },
- };
- /**
- * Data for tracking the robot's movement
- */
- const mapData = {
- /**
- * Tiles we've painted, value is the current color
- */
- grid: new Map(),
- /**
- * Unique number of tiles we've painted
- */
- uniquePaintings: 0,
- /**
- * The current coordinates of the robot
- */
- position: {
- x: 0,
- y: 0,
- },
- /**
- * The current direction the robot is facing
- */
- vector: Vectors.NORTH,
- /**
- * Paint the tile below the robot a given color
- *
- * @param {number} tileColor The new color for the tile below the robot
- * @returns {void}
- */
- PaintTile: function (tileColor) {
- const hashMapKey = `${this.position.x},${this.position.y}`;
- const uniqueTile = this.grid.get(hashMapKey) === undefined;
- this.grid.set(hashMapKey, tileColor);
- if (uniqueTile) {
- this.uniquePaintings++;
- }
- },
- /**
- * Set the heading for the robot
- *
- * @param {boolean} rotateLeft Should the robot rotate left? If not, rotate right
- * @returns {void}
- */
- SetHeading: function (rotateLeft) {
- switch (this.vector) {
- case Vectors.NORTH:
- // console.log(`DEBUG: Facing North, turning ${rotateLeft ? "West" : "East"}`);
- this.vector = rotateLeft ? Vectors.WEST : Vectors.EAST;
- break;
- case Vectors.SOUTH:
- // console.log(`DEBUG: Facing South, turning ${rotateLeft ? "East" : "West"}`);
- this.vector = rotateLeft ? Vectors.EAST : Vectors.WEST;
- break;
- case Vectors.EAST:
- // console.log(`DEBUG: Facing West, turning ${rotateLeft ? "North" : "South"}`);
- this.vector = rotateLeft ? Vectors.NORTH : Vectors.SOUTH;
- break;
- case Vectors.WEST:
- // console.log(`DEBUG: Facing East, turning ${rotateLeft ? "South" : "North"}`);
- this.vector = rotateLeft ? Vectors.SOUTH : Vectors.NORTH;
- break;
- default:
- throw new Error("Wuh?");
- }
- },
- /**
- * Move the robot along the current vector
- * @returns {void}
- */
- Move: function () {
- this.position.x += this.vector.x;
- this.position.y += this.vector.y;
- },
- };
- // Create and run the computer, Robby
- const robby = new Computer(input);
- robby.Run();
- // Start Robby on a white tile
- mapData.grid.set("0,0", 1);
- // Increase by one to account for previous line
- mapData.uniquePaintings++;
- let loopCount = 0;
- do {
- const currentColor = mapData.grid.get(`${mapData.position.x},${mapData.position.y}`) ?? 0;
- robby.Input(currentColor);
- const nextColor = robby.FetchOutputValue();
- const nextRotation = robby.FetchOutputValue();
- mapData.SetHeading(nextRotation == 0);
- mapData.PaintTile(nextColor);
- mapData.Move();
- if (++loopCount > 10_000_000) { console.error("Loop went on for too long."); process.exit(0); }
- } while (robby.running);
- console.log(`Total unique painted tiles: ${mapData.uniquePaintings}`);
- // Image data for Registration Identifier
- let imageData = [];
- // Loop over grid to key coords and their colors
- mapData.grid.forEach((color, coords) => {
- const [row, column] = coords.split(",");
- if (!imageData[column]) { imageData[column] = []; }
- imageData[column][row] = color;
- });
- // Flatten it into one array, and replace undefined's with null's
- imageData = imageData.map(fillEmptySlotsWithZero)
- .map((row) => { while (row.length < 43) { row.push(0); } return row; })
- .flat();
- // Join it into a data stream
- imageData = imageData.join("");
- // Create and render the image
- // Height was found from this post: https://old.reddit.com/r/adventofcode/comments/e93d3y/2019_day_11_part_2_animated_python_output/
- // Width was brute forced
- const height = 6;
- const width = 43;
- // Render Robby's path as a Space Image
- const identifier = new SpaceImageFormat(width, height, imageData);
- identifier.Render();
- console.log();
- /**
- * Fill empty slots in an array with zeros
- *
- * @param {array} arr The array to fill
- * @returns {array} The input array with no empty spots
- */
- function fillEmptySlotsWithZero(arr) {
- return Array.from(arr, (_, i) => {
- if (!(i in arr)) { return 0; }
- return arr[i];
- });
- }
|