Day 21 solved.
This commit is contained in:
parent
f09b1fc787
commit
8bc0ff81c3
134
2020/day21.go
Normal file
134
2020/day21.go
Normal file
|
@ -0,0 +1,134 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"git.annabunch.es/annabunches/adventofcode/2020/lib/util"
|
||||
)
|
||||
|
||||
// could optimize this better with maps, but we'll just do this. Our data set should be small enough
|
||||
func intersection(a, b []string) (result []string) {
|
||||
result = make([]string, 0)
|
||||
for _, av := range a {
|
||||
for _, bv := range b {
|
||||
if av == bv {
|
||||
result = append(result, av)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func includes(list []string, item string) bool {
|
||||
for _, cmp := range list {
|
||||
if cmp == item {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func remove(list []string, item string) []string {
|
||||
for i, cmp := range list {
|
||||
if cmp == item {
|
||||
return append(list[:i], list[i+1:]...)
|
||||
}
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
func parseInput(input []string) (ingredients map[string]int, allergens map[string][]string) {
|
||||
re := regexp.MustCompile("^(.*) \\(contains (.*)\\)")
|
||||
allergens = make(map[string][]string)
|
||||
ingredients = make(map[string]int)
|
||||
for _, line := range input {
|
||||
data := re.FindStringSubmatch(line)
|
||||
is := strings.Split(data[1], " ")
|
||||
as := strings.Split(data[2], ", ")
|
||||
|
||||
for _, ingredient := range is {
|
||||
ingredients[ingredient]++
|
||||
}
|
||||
|
||||
for _, allergen := range as {
|
||||
if ingredients, ok := allergens[allergen]; ok {
|
||||
allergens[allergen] = intersection(is, ingredients)
|
||||
} else {
|
||||
allergens[allergen] = is
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func findUniqueSolution(aMap map[string][]string) {
|
||||
done := false
|
||||
for !done {
|
||||
done = true
|
||||
for a1, is1 := range aMap {
|
||||
if len(is1) == 1 {
|
||||
ingredient := is1[0]
|
||||
for a2, is2 := range aMap {
|
||||
if a1 == a2 {
|
||||
continue
|
||||
}
|
||||
aMap[a2] = remove(is2, ingredient)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, is := range aMap {
|
||||
if len(is) > 1 {
|
||||
done = false
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
step := os.Args[1]
|
||||
values := util.InputParserStrings(os.Args[2])
|
||||
ingredients, allergenMap := parseInput(values)
|
||||
|
||||
switch step {
|
||||
case "1":
|
||||
loose := make([]string, 0)
|
||||
for ingredient, _ := range ingredients {
|
||||
found := false
|
||||
for _, is := range allergenMap {
|
||||
if includes(is, ingredient) {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
loose = append(loose, ingredient)
|
||||
}
|
||||
}
|
||||
|
||||
total := 0
|
||||
for _, i := range loose {
|
||||
total += ingredients[i]
|
||||
}
|
||||
fmt.Println(total)
|
||||
case "2":
|
||||
findUniqueSolution(allergenMap)
|
||||
keys := make([]string, 0)
|
||||
for k, _ := range allergenMap {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
result := ""
|
||||
sort.Strings(keys)
|
||||
for _, k := range keys {
|
||||
result = result + "," + allergenMap[k][0]
|
||||
}
|
||||
fmt.Println(strings.Trim(result, ","))
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user