87 lines
1.7 KiB
Go
87 lines
1.7 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
type Bags map[string][]Bag
|
|
type Bag struct {
|
|
Count int
|
|
Color string
|
|
}
|
|
|
|
// recursively look for a shiny gold bag
|
|
func HasShinyGold(bags Bags, b string, c []Bag) bool {
|
|
t := false
|
|
if len(c) == 0 { // dead end
|
|
return false
|
|
}
|
|
for _, s := range c {
|
|
if s.Color == "shiny gold" { // end of the search
|
|
return true
|
|
} else {
|
|
x := HasShinyGold(bags, s.Color, bags[s.Color])
|
|
if x == true {
|
|
t = true
|
|
}
|
|
}
|
|
|
|
}
|
|
return t
|
|
}
|
|
|
|
func CountBags(bags Bags, bag Bag, mul int) int {
|
|
fmt.Printf("#%v\t%d\n", bag, mul)
|
|
c := bags[bag.Color]
|
|
if len(c) == 0 { // dead end
|
|
return 0
|
|
}
|
|
var s int
|
|
for _, b := range c {
|
|
s += b.Count * mul
|
|
s += CountBags(bags, b, b.Count*mul)
|
|
}
|
|
return s
|
|
}
|
|
|
|
func main() {
|
|
// failed regex that might be worth revisiting:
|
|
//linere, err := regexp.Compile(`(\w+ \w+) bags contain (?:\d+ (\w+ \w+) bags?, )*?\d+ (\w+ \w+) bags?\.`)
|
|
d, _ := ioutil.ReadFile("input")
|
|
lines := strings.Split(string(d), "\n")
|
|
bags := make(Bags)
|
|
for _, l := range lines {
|
|
halves := strings.Split(l, "contain")
|
|
colors := make([]Bag, 0)
|
|
if len(halves) < 2 {
|
|
break
|
|
}
|
|
t := strings.TrimSuffix(halves[0], " bags ")
|
|
if halves[1] == " no other bags." {
|
|
colors = []Bag{}
|
|
} else {
|
|
s := strings.Split(halves[1], ",")
|
|
for _, b := range s {
|
|
f := strings.Fields(b)
|
|
count, _ := strconv.Atoi(f[0])
|
|
colors = append(colors, Bag{
|
|
Color: f[1] + " " + f[2],
|
|
Count: count})
|
|
}
|
|
}
|
|
bags[t] = colors
|
|
}
|
|
total := 0
|
|
for bag, contents := range bags {
|
|
t := HasShinyGold(bags, bag, contents)
|
|
if t == true {
|
|
total += 1
|
|
}
|
|
}
|
|
fmt.Println(total)
|
|
fmt.Println(CountBags(bags, Bag{Color: "shiny gold"}, 1))
|
|
}
|