package day19 import ( "sort" "strings" ) func Part1(input string) int { in := strings.Split(input, "\n\n") towels := strings.Split(in[0], ", ") patterns := strings.Split(in[1], "\n") // fmt.Println(towels, patterns) count := 0 not_possibles := make(map[string]bool) for _, pattern := range patterns { if isPossible(towels, pattern, not_possibles) { // fmt.Println(count, pattern) count++ } } return count } func Part2(input string) int { in := strings.Split(input, "\n\n") towels := strings.Split(in[0], ", ") sort.Strings(towels) patterns := strings.Split(in[1], "\n") // fmt.Println(towels, patterns) count := 0 memo := make(map[string]int) for _, pattern := range patterns { count += countPossible(sortStringsByPrefix(towels), pattern, memo) } return count } func isPossible(towels []string, pattern string, not_possibles map[string]bool) bool { if pattern == "" { return true } if not_possibles[pattern] { return false } for _, towel := range towels { if strings.HasPrefix(pattern, towel) { if isPossible(towels, pattern[len(towel):], not_possibles) { return true } } } not_possibles[pattern] = true return false } func countPossible(towels map[byte][]string, pattern string, memo map[string]int) int { if pattern == "" { return 1 } //If memo has key if val, ok := memo[pattern]; ok { return val } count := 0 for _, towel := range towels[pattern[0]] { if strings.HasPrefix(pattern, towel) { count += countPossible(towels, pattern[len(towel):], memo) } } memo[pattern] = count return count } func sortStringsByPrefix(slice []string) map[byte][]string { result := make(map[byte][]string) for _, str := range slice { result[str[0]] = append(result[str[0]], str) } for _, t := range result { sort.Strings(t) } return result }