106 lines
2.7 KiB
JavaScript
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();
|