Day 14 WIP

This commit is contained in:
2022-06-11 16:40:57 -05:00
parent 46cb381e8d
commit 060cfeb610
8 changed files with 261 additions and 0 deletions

149
days/14.go Normal file
View File

@ -0,0 +1,149 @@
package days
import (
"fmt"
"strconv"
"strings"
u "parnic.com/aoc2019/utilities"
)
type reaction struct {
inputs map[string]int
output u.Pair[string, int]
}
type Day14 struct {
reactions []reaction
leftovers map[string]int
}
func (d *Day14) Parse() {
d.leftovers = make(map[string]int)
lines := u.GetStringLines("14s2")
d.reactions = make([]reaction, len(lines))
for i, line := range lines {
sides := strings.Split(line, " => ")
inputs := strings.Split(sides[0], ", ")
output := sides[1]
outPair := strings.Split(output, " ")
outAmt, _ := strconv.Atoi(outPair[0])
d.reactions[i].output = u.Pair[string, int]{First: outPair[1], Second: outAmt}
d.reactions[i].inputs = make(map[string]int)
for _, input := range inputs {
pair := strings.Split(input, " ")
d.reactions[i].inputs[pair[1]], _ = strconv.Atoi(pair[0])
}
}
}
func (d Day14) getReactionProducing(chem string) *reaction {
for _, reaction := range d.reactions {
if reaction.output.First == chem {
return &reaction
}
}
return nil
}
func (d Day14) Num() int {
return 14
}
func (d Day14) getOreRequiredFor(chem string, amt int) (int, int) {
requiredOre := 0
for _, reaction := range d.reactions {
if reaction.output.First == chem {
// if oreAmt, exists := reaction.inputs["ORE"]; exists && len(reaction.inputs) == 1 {
// if d.leftovers[chem] >= amt {
// d.leftovers[chem] -= amt
// return 0, amt
// }
// produced := reaction.output.Second
// for produced < amt {
// requiredOre += oreAmt
// produced += reaction.output.Second
// }
// requiredOre += oreAmt
// if produced > amt {
// d.leftovers[chem] += produced - amt
// }
// return requiredOre, produced
// } else {
for inChem, inAmt := range reaction.inputs {
produced := 0
if d.leftovers[inChem] >= inAmt {
d.leftovers[inChem] -= inAmt
produced = inAmt
} else {
for produced < inAmt {
madeOre, madeChem := d.getOreRequiredFor(inChem, inAmt)
produced += madeChem
requiredOre += madeOre
}
if produced > inAmt {
d.leftovers[inChem] += produced - inAmt
}
}
}
// }
}
}
return requiredOre, 0
}
func (d *Day14) Part1() string {
fuelReaction := d.getReactionProducing("FUEL")
if fuelReaction == nil {
panic("")
}
neededMaterial := map[string]int{
"FUEL": 1,
}
var recurse func(neededMaterial map[string]int) map[string]int
recurse = func(neededMaterial map[string]int) map[string]int {
neededInputs := make(map[string]int)
for chem, amt := range neededMaterial {
reaction := d.getReactionProducing(chem)
if reaction == nil {
continue
}
produced := reaction.output.Second
reactionsNeeded := 1
for produced < amt {
produced += reaction.output.Second
reactionsNeeded++
}
for inChem, inAmt := range reaction.inputs {
neededInputs[inChem] += inAmt * reactionsNeeded
}
}
if len(neededInputs) > 0 {
recursed := recurse(neededInputs)
for k, v := range recursed {
neededInputs[k] += v
}
}
return neededInputs
}
recursed := recurse(neededMaterial)
fmt.Println(len(recursed))
ore := 0
for inChem, inAmt := range fuelReaction.inputs {
requiredOre, _ := d.getOreRequiredFor(inChem, inAmt)
ore += requiredOre
}
return fmt.Sprintf("%s%d%s", u.TextBold, ore, u.TextReset)
}
func (d *Day14) Part2() string {
return ""
}