advent-of-code/2022/17/index2.js

136 lines
3.4 KiB
JavaScript
Raw Normal View History

2022-12-19 09:09:03 +00:00
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();