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();