package main import ( "fmt" "sort" "strings" h "git.bullercodeworks.com/brian/adventofcode/helpers" ) func main() { fmt.Println("# Day 21") inp := h.StdinToStringSlice() solve(inp) } func solve(inp []string) { var allergens []string var ings []string allergenToIng := make(map[string][]string) for k := range inp { pts := strings.Split(inp[k], " (contains ") if len(pts) > 1 { pts[1] = strings.TrimSuffix(pts[1], ")") } dishIngs := strings.Split(pts[0], " ") ings = h.UnionStringSlice(dishIngs, ings) algns := strings.Split(pts[1], ", ") allergens = h.UnionStringSlice(algns, allergens) for ak := range algns { prev := allergenToIng[algns[ak]] if len(prev) == 0 { allergenToIng[algns[ak]] = dishIngs } else { allergenToIng[algns[ak]] = h.IntersectStringSlice(prev, dishIngs) } } } sort.Strings(allergens) found := make(map[string]string) for len(allergenToIng) > 0 { for a, i := range allergenToIng { if len(i) == 1 { found[a] = i[0] delete(allergenToIng, a) } } for a, i := range allergenToIng { // Remove all found allergens for f := range found { if k := h.StringSliceIndex(i, found[f]); k > -1 { allergenToIng[a] = append(i[:k], i[k+1:]...) } } } } var badIngs []string for f := range found { badIngs = append(badIngs, found[f]) if k := h.StringSliceIndex(ings, found[f]); k > -1 { ings = append(ings[:k], ings[k+1:]...) } } var total int for k := range inp { food := strings.Fields(strings.Split(inp[k], " (contains")[0]) for fk := range food { for j := range ings { if food[fk] == ings[j] { total++ } } } } fmt.Printf("## Part 1:\nAnswer: %d\n", total) badIngs = []string{} for k := range allergens { badIngs = append(badIngs, found[allergens[k]]) } fmt.Printf("## Part 2:\nAnswer:\n%s\n", strings.Join(badIngs, ",")) }