advent-of-code/2022/19/index.js

106 lines
2.7 KiB
JavaScript

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 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()
}))
}
const coords = ([x, y, z]) => `${x},${y},${z}`;
const createPlan = ([id, orO, crO, obrO, obrC, grO, grObs]) => {
return {
id,
botCosts: {
ore: {ore: orO},
clay: {ore: crO},
obs: {
ore: obrO,
clay: obrC
},
geo: {
ore: grO,
obs: grObs
}
},
maxBotNeed: {
ore: Math.max(orO, crO, obrO, grO),
clay: obrC,
obs: grObs,
geo: Infinity
}
}
};
let exhaustedPossibilities = 0;
const runPlan = (
plan,
buildNext,
bots = {ore: 1, clay: 0, obs: 0, geo: 0},
resources = {ore: 0, clay: 0, obs: 0, geo: 0},
time=24
) => {
if(time < 1) {
exhaustedPossibilities++;
if(exhaustedPossibilities % 1000000 === 0) {
console.log("Tried ", exhaustedPossibilities, " possible outcomes");
}
return resources.geo;
}
const {maxBotNeed, botCosts} = plan;
const nextResources = Object.entries(resources).reduce((next, [type, count]) => {
next[type] = count + bots[type];
return next;
}, {});
let nextBots = bots;
const canBuild = buildNext && Object.entries(botCosts[buildNext]).every(([type, needed]) => resources[type] >= needed);
if(canBuild) {
nextBots = {...bots, [buildNext]: bots[buildNext] + 1};
for(const type in botCosts[buildNext]) {
nextResources[type] -= botCosts[buildNext][type];
}
buildNext = undefined;
}
if(buildNext) {
return runPlan(plan, buildNext, nextBots, nextResources, time -1);
}
const outcomes = Object.entries(botCosts).filter(([k]) => k !== "id").map(([type, costs]) => {
for(const key in costs) {
if(!nextBots[key]) {
return 0;
}
}
if(nextBots[type] >= maxBotNeed[type]) {
return 0;
}
return runPlan(plan, type, nextBots, nextResources, time - 1);
});
return Math.max(...outcomes);
};
const main = async () => {
const input = (await fs.readFile("./input.txt", 'utf8')).slice(0, -1).split("\n");
const plans = input.map(p => createPlan(p.match(/\d+/g).map(x => parseInt(x))));
const results = plans.map(plan => plan.id * Math.max(runPlan(plan, "ore"), runPlan(plan, "clay")));
console.log("Answer: ", sum(results));
}
main();