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(rockBottom <= tallestPoint && 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; let lastCount = 0; let lastHeight = 0; let firstCountDiff = 0; let firstHeightDiff = 0; let lastCountDiff = 0; let lastHeightDiff = 0; const target = 1000000000000; const letFall = () => { if(jetTracker === 0) { lastCountDiff = shapeCount - lastCount; lastHeightDiff = tallestPoint - lastHeight; if(!firstCountDiff) { firstCountDiff = lastCountDiff; } if(!firstHeightDiff) { firstHeightDiff = lastHeightDiff; } lastCount = shapeCount; lastHeight = tallestPoint; } 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; } } }; while(shapeCount < 50000) { letFall(); } let answer = firstHeightDiff + Math.floor((target - firstCountDiff) / lastCountDiff) * lastHeightDiff; const neededDiffForRemainder = (target - firstCountDiff) % lastCountDiff; let neededRemainder; while(shapeCount < 200000) { letFall(); if((shapeCount - firstCountDiff) % lastCountDiff === neededDiffForRemainder) { console.log("Fount it!"); neededRemainder = tallestPoint - lastHeight; } } answer += neededRemainder; console.log("Answer: ", answer); } main();