87 lines
1.8 KiB
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
|
||
|
}
|