89 lines
1.8 KiB
Go
89 lines
1.8 KiB
Go
package main
|
|
|
|
import (
|
|
"AoC2020/helper"
|
|
"fmt"
|
|
"os"
|
|
"regexp"
|
|
"strings"
|
|
)
|
|
|
|
var possibleBag []string
|
|
var rules map[string]string
|
|
|
|
func main() {
|
|
args := os.Args[1:]
|
|
input, err := helper.GetInput(args[0])
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
rules = getRules(input)
|
|
part1([]string{"shiny gold bag"}, []string{})
|
|
fmt.Println(len(possibleBag))
|
|
fmt.Println(part2("shiny gold bag")-1)
|
|
}
|
|
|
|
func getRules(input []string) map[string]string {
|
|
var m = make(map[string]string)
|
|
for _, rule := range input {
|
|
r, _ := regexp.Compile("[0-9]? ?[a-z]* [a-z]* bag")
|
|
parsedRule := r.FindAllString(rule, -1)
|
|
m[parsedRule[0]] = strings.Join(parsedRule[1:], " ")
|
|
}
|
|
return m
|
|
}
|
|
|
|
func part1(checkBags []string, considered []string) {
|
|
foundBags := []string{}
|
|
for _, bag := range checkBags {
|
|
for key, value := range rules {
|
|
if strings.Contains(value, bag) && !stringInSlice(key, considered) {
|
|
foundBags = append(foundBags, key)
|
|
considered = append(considered, key)
|
|
possibleBag = append(possibleBag, key)
|
|
}
|
|
}
|
|
}
|
|
foundBags = removeDuplicateValues(foundBags)
|
|
if len(foundBags) > 0 {
|
|
part1(foundBags, considered)
|
|
} else {
|
|
return
|
|
}
|
|
}
|
|
|
|
func part2(checkbag string) int {
|
|
r, _ := regexp.Compile("[0-9]? ?[a-z]* [a-z]* bag")
|
|
nextBags := r.FindAllString(rules[checkbag], -1)
|
|
sum := 0
|
|
for _, bag := range nextBags {
|
|
if bag[0] >= 49 && bag[0] <= 57 {
|
|
amount := int(bag[0] - 48)
|
|
sum += amount * part2(bag[2:])
|
|
}
|
|
}
|
|
return sum + 1
|
|
}
|
|
|
|
func stringInSlice(a string, list []string) bool {
|
|
for _, b := range list {
|
|
if b == a {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func removeDuplicateValues(stringSlice []string) []string {
|
|
keys := make(map[string]bool)
|
|
list := []string{}
|
|
|
|
for _, entry := range stringSlice {
|
|
if _, value := keys[entry]; !value {
|
|
keys[entry] = true
|
|
list = append(list, entry)
|
|
}
|
|
}
|
|
return list
|
|
}
|