91 lines
1.8 KiB
Go
91 lines
1.8 KiB
Go
package day19
|
|
|
|
import (
|
|
"strings"
|
|
)
|
|
|
|
func Part1(input string) int {
|
|
towelPatterns, designs := parseInput(input)
|
|
result := countPossibleDesigns(towelPatterns, designs)
|
|
return result
|
|
}
|
|
|
|
func Part2(input string) int {
|
|
towelPatterns, designs := parseInput(input)
|
|
result := totalArrangements(towelPatterns, designs)
|
|
return result
|
|
}
|
|
|
|
func parseInput(input string) ([]string, []string) {
|
|
parts := strings.SplitN(input, "\n\n", 2)
|
|
towels := strings.Split(strings.ReplaceAll(parts[0], " ", ""), ",")
|
|
patterns := strings.Split(strings.TrimSpace(parts[1]), "\n")
|
|
return towels, patterns
|
|
}
|
|
|
|
func countPossibleDesigns(towelPatterns []string, designs []string) int {
|
|
memo := make(map[string]bool)
|
|
count := 0
|
|
|
|
for _, design := range designs {
|
|
if canConstruct(design, towelPatterns, memo) {
|
|
count++
|
|
}
|
|
}
|
|
|
|
return count
|
|
}
|
|
|
|
func canConstruct(design string, patterns []string, memo map[string]bool) bool {
|
|
if design == "" {
|
|
return true
|
|
}
|
|
if val, found := memo[design]; found {
|
|
return val
|
|
}
|
|
|
|
for _, pattern := range patterns {
|
|
if strings.HasPrefix(design, pattern) {
|
|
remaining := design[len(pattern):]
|
|
if canConstruct(remaining, patterns, memo) {
|
|
memo[design] = true
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
|
|
memo[design] = false
|
|
return false
|
|
}
|
|
|
|
func totalArrangements(towelPatterns []string, designs []string) int {
|
|
memo := make(map[string]int)
|
|
total := 0
|
|
|
|
for _, design := range designs {
|
|
total += countWays(design, towelPatterns, memo)
|
|
}
|
|
|
|
return total
|
|
}
|
|
|
|
func countWays(design string, patterns []string, memo map[string]int) int {
|
|
if design == "" {
|
|
return 1
|
|
}
|
|
if val, found := memo[design]; found {
|
|
return val
|
|
}
|
|
|
|
totalWays := 0
|
|
for _, pattern := range patterns {
|
|
if strings.HasPrefix(design, pattern) {
|
|
remaining := design[len(pattern):]
|
|
totalWays += countWays(remaining, patterns, memo)
|
|
}
|
|
}
|
|
|
|
memo[design] = totalWays
|
|
return totalWays
|
|
}
|