17 was a pain, but I did it
This commit is contained in:
parent
8080091870
commit
15ebc5c200
4 changed files with 262 additions and 0 deletions
1
2022/17/example.txt
Normal file
1
2022/17/example.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
>>><<><>><<<>><>>><<<>>><<<><<<>><>><<>>
|
125
2022/17/index.js
Normal file
125
2022/17/index.js
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
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();
|
135
2022/17/index2.js
Normal file
135
2022/17/index2.js
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
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();
|
1
2022/17/input.txt
Normal file
1
2022/17/input.txt
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue