88 lines
1.8 KiB
Go
88 lines
1.8 KiB
Go
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
|
|
}
|