github.com/dds/aoc2020@v1.9.84/day7/day7.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "strconv" 6 "strings" 7 8 "github.com/dds/aoc2020/lib" 9 "github.com/dds/aoc2020/lib/inputs" 10 ) 11 12 func parse(s string) []string { 13 parts := lib.TrimSpace(strings.Split(s, "bags contain")) 14 if len(parts) < 2 { 15 return []string{} 16 } 17 bags := strings.Split(parts[1], ", ") 18 r := []string{parts[0]} 19 // Drop the last word from each group. 20 for _, b := range bags { 21 t := strings.Fields(b) 22 r = append(r, strings.Join(t[:len(t)-1], " ")) 23 } 24 return r 25 } 26 27 var Input = lib.ParseInput(inputs.Day7(), parse) 28 29 func part1(input [][]string) (rc int) { 30 m := map[string][]string{} 31 for _, row := range input { 32 for _, s := range row[1:] { 33 bag := s[2:] 34 m[bag] = append(m[bag], row[0]) 35 } 36 } 37 bagQueue := []string{"shiny gold"} 38 seenBags := map[string]int{} 39 for len(bagQueue) > 0 { 40 bag := bagQueue[0] 41 bagQueue = bagQueue[1:] 42 for _, u := range m[bag] { 43 if seenBags[u] == 1 { 44 continue 45 } 46 seenBags[u] = 1 47 bagQueue = append(bagQueue, u) 48 rc++ 49 } 50 } 51 return 52 } 53 54 func part2(input [][]string) (rc int) { 55 type bagCount struct { 56 count int 57 bag string 58 } 59 m := map[string][]bagCount{} 60 for _, row := range input { 61 for _, s := range row[1:] { 62 count, err := strconv.Atoi(s[:1]) 63 if err != nil { 64 count = 0 65 } 66 bag := s[2:] 67 m[row[0]] = append(m[row[0]], bagCount{count: count, bag: bag}) 68 } 69 } 70 var count func(map[string][]bagCount, string) int 71 count = func(m map[string][]bagCount, bag string) (sum int) { 72 for _, u := range m[bag] { 73 sum += u.count * (1 + count(m, u.bag)) 74 } 75 return sum 76 } 77 return count(m, "shiny gold") 78 } 79 80 func main() { 81 fmt.Println(part1(Input)) 82 fmt.Println(part2(Input)) 83 }