diff --git a/2019/day14/main.go b/2019/day14/main.go index 37bc391..a55d0ac 100644 --- a/2019/day14/main.go +++ b/2019/day14/main.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "math" "strings" helpers "git.bullercodeworks.com/brian/adventofcode/helpers" @@ -29,6 +30,64 @@ func part1(inp []string) { } func part2(inp []string) { + fuel := GetMaxFuelForOre(inp, 1000000000000) + fmt.Println("# Part 2") + fmt.Println("Fuel:", fuel) +} + +func FindRequiredOre(inp []string, fuel int) int { + allReactions := make(map[string]*Reaction) + for _, v := range inp { + r := NewReaction(v) + allReactions[r.out] = r + } + return Produce("FUEL", fuel, allReactions, make(map[string]int)) +} + +func Produce(chem string, amt int, allReactions map[string]*Reaction, excess map[string]int) int { + if chem == "ORE" { + return amt + } + if excess[chem] >= amt { + excess[chem] -= excess[chem] + excess[chem] = 0 + } + recipe := allReactions[chem] + times := int(math.Ceil(float64(amt) / float64(recipe.outQty))) + ret := 0 + for k, inAmt := range recipe.in { + ret += Produce(k, inAmt*times, allReactions, excess) + } + numProduced := times * recipe.outQty + excess[chem] += numProduced - amt + return ret +} + +func GetMaxFuelForOre(inp []string, ore int) int { + var start, guesses, lastGuess, fuelGuess int + end := ore + for { + guesses++ + fuelGuess = (end-start)/2 + start + requiredOre := FindRequiredOre(inp, fuelGuess) + if requiredOre == ore { + break + } + if requiredOre > ore { + end = fuelGuess + } else { + start = fuelGuess + } + if fuelGuess == lastGuess { + break + } + lastGuess = fuelGuess + } + return fuelGuess +} + +// this is too slow... Gonna re-engineer it... +func part2Slow(inp []string) { allReactions = make(map[string]*Reaction) for _, v := range inp { r := NewReaction(v)