package two import ( "bytes" "cmp" "slices" "strings" log "github.com/sirupsen/logrus" ) func Solve(buf []byte) (int, error) { r := bytes.NewReader(buf) stripes, designs, err := parseLines(r) if err != nil { return 0, err } conc := len(designs) countChan := make(chan int) for _, design := range designs { go func() { count, ok := numPossibleArrangement(design, stripes, make(map[string]int)) if ok { log.Debugf("design: %s is possible in %d ways", design, count) countChan <- count return } countChan <- 0 }() } var totalCount int for range conc { count := <-countChan totalCount += count } return totalCount, nil } func numPossibleArrangement(design string, stripes []string, memo map[string]int) (int, bool) { if len(design) == 0 { return 1, true } greedy := []string{} for _, stripe := range stripes { if strings.HasPrefix(design, stripe) { greedy = append(greedy, stripe) } } slices.SortFunc(greedy, func(a, b string) int { return cmp.Compare(len(b), len(a)) }) var totalCount int for _, g := range greedy { if count, ok := memo[design[len(g):]]; ok { totalCount += count continue } count, ok := numPossibleArrangement(design[len(g):], stripes, memo) if ok { totalCount += count } memo[design[len(g):]] = count } return totalCount, true }