Files
adventofcode/2024/gareth/day19/day19.go
2025-01-13 23:48:55 +00:00

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
}