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 }