namespace AdventOfCode2019_14_2 { const DAY = 14; const PROBLEM = 2; export async function run() { let input = await AdventOfCode.getInput(DAY); if (input == null) return; let recipes: { [_:string]:[number, [number, string][], string ] } = {}; for (let line of input.split(new RegExp('\r?\n')).filter(p => p.trim().length > 0)) { const left = line.split(" => ")[0]; const right = line.split(" => ")[1]; const right_n = parseInt(right.split(" ")[0]); const right_v = right.split(" ")[1]; recipes[right_v] = [ right_n, left.split(", ").map(p => [ parseInt(p.split(" ")[0]), p.split(" ")[1] ] ), line ]; } // binary search const target = 1_000_000_000_000; let lower = 1; let upper = 1_000_000_000_000; AdventOfCode.outputConsole(`Range: [${lower} | ${upper}]`); while(upper-lower>1) { const f = Math.floor((upper+lower) / 2); const o = calcOreRequirement(recipes, f); AdventOfCode.outputConsole(`${o} ORE => ${f} FUEL`); if (o > target) { upper = f; } else if (o < target) { lower = f; } else { upper = lower = f; // jackpot } AdventOfCode.outputConsole(`Range: [${lower} | ${upper}]`); } AdventOfCode.output(DAY, PROBLEM, lower.toString()); } function calcOreRequirement(recipes: { [_:string]:[number, [number, string][], string ] }, fuelcount: number): number { let missing : [number, string][] = [ [fuelcount, "FUEL"] ]; let surplus : [number, string][] = []; while( missing.length>1 || missing[0][1] !== "ORE" ) { missing = missing.filter(p => p[0]>0); surplus = surplus.filter(p => p[0]>0); //AdventOfCode.outputConsole("missing: [" + missing.map(p => p[0]+"|"+p[1]).reduce((a,b)=>a+" "+b, "")+"]"); //AdventOfCode.outputConsole("surplus: [" + surplus.map(p => p[0]+"|"+p[1]).reduce((a,b)=>a+" "+b, "")+"]"); let target = missing.pop(); if (target === undefined) throw "undef??"; if (target[1] === "ORE") { missing.push(target); missing = missing.reverse(); target = missing.pop(); if (target === undefined) throw "undef??"; } const orig_recipe = recipes[target[1]]; const factor = Math.max(1, Math.ceil(target[0] / orig_recipe[0])); let recipe: [number, [number, string][], string] = [ factor*orig_recipe[0], Object.assign([], orig_recipe[1]).map(p => [ factor*p[0], p[1] ] ), (""+factor+"*("+orig_recipe[2]+")") ]; if (target[0] > recipe[0]) { missing.push([ target[0] - recipe[0], target[1] ]); } else if (target[0] < recipe[0]) { let found=false; for(let i=0; i= incred_count) { surplus[i][0] -= incred_count; incred_count = 0; } else { incred_count -= surplus[i][0]; surplus[i][0] = 0; } } } if (incred_count > 0) { let found=false; for(let i=0; i