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 }