package main import ( "fmt" "strings" h "git.bullercodeworks.com/brian/adventofcode/helpers" ) var cache map[string]int func main() { inp := h.StdinToStringSlice() cache = make(map[string]int) part1(inp) fmt.Println() part2(inp) } func part1(inp []string) { available, want := parseTowels(inp) fmt.Println("# Part 1") var possible int for i := range want { if build(want[i], available) > 0 { possible++ } } fmt.Println("Possible Designs:", possible) } func part2(inp []string) { available, want := parseTowels(inp) fmt.Println("# Part 2") var possible int for i := range want { possible += build(want[i], available) } fmt.Println("Possible Designs:", possible) } func build(towel string, from []string) int { if _, ok := cache[towel]; !ok { if len(towel) == 0 { return 1 } res := 0 for _, p := range from { if strings.HasPrefix(towel, p) { res += build(towel[len(p):], from) } } cache[towel] = res } return cache[towel] } /* Slow solution... func build(towel string, from []string) bool { if len(towel) == 0 { return true } for i := range from { if len(from[i]) > len(towel) { continue } var nextFrom bool for j := 0; j < len(from[i]); j++ { if towel[j] != from[i][j] { nextFrom = true break } } // This 'from' didn't match if nextFrom { continue } if build(towel[len(from[i]):], from) { return true } } return false } */ func parseTowels(inp []string) ([]string, []string) { var available, want []string pts := strings.Split(inp[0], ", ") for i := range pts { p := strings.TrimSpace(pts[i]) available = append(available, p) } for _, n := range inp[2:] { want = append(want, n) } return available, want }