const fs = require('fs/promises'); const sum = (arr) => arr.reduce((total, num) => total+num, 0); const arrayOfLength = n => Array.from(Array(n).keys()).map(() => {}); //minus const shapes = [ [[2,0],[3,0],[4,0],[5,0]], [[3,0],[2,1],[3,1],[4,1],[3,2]], [[2,0],[3,0],[4,0],[4,1],[4,2]], [[2,0],[2,1],[2,2],[2,3]], [[2,0],[3,0],[2,1],[3,1]] ]; const keypress = async () => { process.stdin.setRawMode(true) return new Promise(resolve => process.stdin.once('data', data => { const byteArray = [...data] if (byteArray.length > 0 && byteArray[0] === 3) { console.log('^C') process.exit(1) } process.stdin.setRawMode(false) resolve() })) } let shapeCount = 0; const getNextShape = (height) => { const shape = shapes[shapeCount % 5]; shapeCount++; return shape.map(([x, y]) => [x, y + height]); } const getTopMost = (rocks) => Math.max(0, ...rocks); const coords = ([x, y]) => `${x}-${y}`; const main = async () => { const input = (await fs.readFile("./input.txt", 'utf8')).slice(0, -1); const fallenRocks = {}; let tallestPoint = 0; const isColiding = (shape) => { if(shape.some(([x]) => x < 0 || x >= 7)) { return true; } if(shape.some(([_, y]) => y <= 0)) { return true; } const rockBottom = Math.min(...shape.map(([_, y]) => y)) if(shape.some(x => fallenRocks[coords(x)])){ return true; } return false; }; const shapeShift = (shape, direction) => { let nextPos; if(direction === "<") { nextPos = shape.map(([x, y]) => [x - 1, y]); } if(direction === ">") { nextPos = shape.map(([x, y]) => [x + 1, y]); } if(direction === "V") { nextPos = shape.map(([x, y]) => [x, y - 1]); } return nextPos && !isColiding(nextPos) ? nextPos : shape; }; let jetTracker = 0; const print = (shape) => { process.stdout.write('\u001b[2J'); process.stdout.write('\u001b[;H'); for(let y = 26; y > 0; --y) { const row = arrayOfLength(7).map((_, x) => { let ch = "."; if(fallenRocks[coords([x,y])]){ ch = "#"; } if(shape.some(([rx, ry]) => x === rx && y === ry)) { ch = "@"; } return ch; }); console.log(["|", ...row, "|"].join('')); } console.log("+-------+"); console.log(fallenRocks); console.log("Upcoming jet direction: ", input[jetTracker]); }; while(shapeCount < 2022) { let shape = getNextShape(tallestPoint + 4) while(true) { const jetMoved = shapeShift(shape, input[jetTracker]); jetTracker = (jetTracker + 1) % input.length; shape = shapeShift(jetMoved, "V") if(shape === jetMoved) { const newTallest = getTopMost(jetMoved.map(([_, y]) => y)); tallestPoint = Math.max(newTallest, tallestPoint); for(const unit of jetMoved) { fallenRocks[coords(unit)] = unit[1]; } break; } } if(!(shapeCount % 25)) { console.log(shapeCount, " rocks have fallen..."); } } console.log("Answer: ", getTopMost(Object.values(fallenRocks))); } main();