improve day 7 perf even more

master
Araozu 2024-03-11 19:35:10 -05:00
parent b6da4f8f81
commit 1426f3a32a
1 changed files with 24 additions and 27 deletions

View File

@ -6,10 +6,12 @@ import (
) )
type Bag struct { type Bag struct {
color string color string
contents []BagContent contents []BagContent
containsShinyGold bool // -1 if not set, 0 if it doesn't contain, 1 if it does
contentsCount int containsShinyGold int
// -1 if not counted yet
contentsCount int
} }
type BagContent struct { type BagContent struct {
@ -25,7 +27,7 @@ func parseBagStatement(bagStatement string) Bag {
// if no aditional bags // if no aditional bags
if bagContentsStr[:2] == "no" { if bagContentsStr[:2] == "no" {
return Bag{color: bagColor, contents: make([]BagContent, 0), contentsCount: -1} return Bag{color: bagColor, contents: make([]BagContent, 0), contentsCount: -1, containsShinyGold: -1}
} }
// parse remainder bags // parse remainder bags
@ -44,38 +46,33 @@ func parseBagStatement(bagStatement string) Bag {
bagContents[idx] = BagContent{count: bagCount, color: bagColor2} bagContents[idx] = BagContent{count: bagCount, color: bagColor2}
} }
/* return Bag{color: bagColor, contents: bagContents, contentsCount: -1, containsShinyGold: -1}
grammar for bag statements:
statement = bag color, "bags contain", (bag list | empty bag), "."
empty bag = "no other bags"
bag list = bag declaration, bag declaration+
bag declaration = number, bag color, "bag", "s"?
bag color = word, word
*/
return Bag{color: bagColor, contents: bagContents, contentsCount: -1}
} }
func bagContainsShinyGold(bagColor string, bagMap map[string]*Bag) bool { func bagContainsShinyGold(bag *Bag, bagMap map[string]*Bag) bool {
bag := bagMap[bagColor] if bag.containsShinyGold == 1 {
if bag.containsShinyGold {
return true return true
} }
if bag.containsShinyGold == 0 {
return false
}
// recursively search // recursively search
for _, nextBag := range bag.contents { for _, nextBag := range bag.contents {
if nextBag.color == "shiny gold" { if nextBag.color == "shiny gold" {
bag.containsShinyGold = true bag.containsShinyGold = 1
return true return true
} }
if bagContainsShinyGold(nextBag.color, bagMap) { nextBagF := bagMap[nextBag.color]
bag.containsShinyGold = true if bagContainsShinyGold(nextBagF, bagMap) {
bag.containsShinyGold = 1
return true return true
} }
} }
bag.containsShinyGold = 0
return false return false
} }
@ -84,20 +81,18 @@ func Day07Part01(isTest bool) int {
groups := strings.Split(input, "\n") groups := strings.Split(input, "\n")
bags := make(map[string]*Bag) bags := make(map[string]*Bag)
bagColors := make([]string, len(groups))
// parse and collect the bags // parse and collect the bags
for i, statement := range groups { for _, statement := range groups {
parsedBag := parseBagStatement(statement) parsedBag := parseBagStatement(statement)
bags[parsedBag.color] = &parsedBag bags[parsedBag.color] = &parsedBag
bagColors[i] = parsedBag.color
} }
shinyGoldContainers := 0 shinyGoldContainers := 0
// process the bags // process the bags
for _, bagColor := range bagColors { for _, bag := range bags {
if bagContainsShinyGold(bagColor, bags) { if bagContainsShinyGold(bag, bags) {
shinyGoldContainers += 1 shinyGoldContainers += 1
} }
} }
@ -120,6 +115,8 @@ func countInnerBags(bag *Bag, bagMap map[string]*Bag) int {
innerBagsCount += nextBagCount + nextBagCount*countInnerBags(nextBag, bagMap) innerBagsCount += nextBagCount + nextBagCount*countInnerBags(nextBag, bagMap)
} }
bag.contentsCount = innerBagsCount
return innerBagsCount return innerBagsCount
} }