adventofcode/2020/day07/main.go

87 lines
1.8 KiB
Go

package main
import (
"fmt"
"strings"
h "git.bullercodeworks.com/brian/adventofcode/helpers"
)
func main() {
fmt.Println("# Day 7")
inp := h.StdinToStringSlice()
allBags := make(map[string]*Bag)
for _, v := range inp {
b := ParseBag(v)
allBags[b.Color] = b
}
// Now fill in all 'contains'
for _, v := range allBags {
for _, cc := range v.ContainsColors {
v.Contains = append(v.Contains, allBags[cc])
}
}
whatIGot := "shiny gold"
var bagsCanContain int
for _, v := range allBags {
if v.CanContain(whatIGot) {
bagsCanContain++
}
}
fmt.Println("## Part 1")
fmt.Printf("My %s bag can be held by %d bags\n\n", whatIGot, bagsCanContain)
fmt.Println("## Part 2")
fmt.Printf("And my bag must contain %d other bags\n", allBags[whatIGot].CountBagsInside())
}
type Bag struct {
Color string
ContainsColors []string
Contains []*Bag
}
func ParseBag(inp string) *Bag {
ret := Bag{}
pts := strings.Split(inp, " bags contain ")
ret.Color = pts[0]
pts[1] = strings.ReplaceAll(pts[1], "bags", "")
pts[1] = strings.ReplaceAll(pts[1], "bag", "")
pts[1] = pts[1][:len(pts[1])-2]
nest := strings.Split(pts[1], ", ")
for _, v := range nest {
space := strings.Index(v, " ")
num, rest := v[:space], strings.TrimSpace(v[space:])
if num != "no" {
count := h.Atoi(num)
for count > 0 {
ret.ContainsColors = append(ret.ContainsColors, rest)
count--
}
}
}
return &ret
}
func (b *Bag) CanContain(color string) bool {
for _, v := range b.ContainsColors {
if v == color {
return true
}
}
for _, v := range b.Contains {
if v.CanContain(color) {
return true
}
}
return false
}
func (b *Bag) CountBagsInside() int {
ret := len(b.Contains)
for _, v := range b.Contains {
ret = ret + v.CountBagsInside()
}
return ret
}