day12, counts but too slow

This commit is contained in:
efim 2023-12-13 02:35:41 +00:00
parent 42b587918e
commit 6398a4d468
2 changed files with 60 additions and 24 deletions

View File

@ -6,12 +6,16 @@ import (
"os" "os"
"strconv" "strconv"
"strings" "strings"
"sync"
"time"
) )
func Run() int { func Run() int {
fmt.Println("hello day 12.") fmt.Println("hello day 12.")
filename := "day12/example1" start := time.Now()
filename := "day12/input"
bytes, err := os.ReadFile(filename) bytes, err := os.ReadFile(filename)
if err != nil { if err != nil {
panic(fmt.Sprintf("error reading file %s\n", filename)) panic(fmt.Sprintf("error reading file %s\n", filename))
@ -32,7 +36,18 @@ func Run() int {
// fmt.Println(variant) // fmt.Println(variant)
// } // }
for _, line := range strings.Split(text, "\n") { var wg sync.WaitGroup
lines := strings.Split(text, "\n")
wg.Add(len(lines))
matches := make(chan int)
go func() {
wg.Wait()
close(matches)
}()
for i, line := range lines {
go func(line string, lineNum int){
mask, blockLengs := ReadLine(line) mask, blockLengs := ReadLine(line)
blockLengthSum := 0 blockLengthSum := 0
@ -40,16 +55,27 @@ func Run() int {
blockLengthSum += blockLen blockLengthSum += blockLen
} }
variants := generatePermutations("", len(mask), blockLengs, blockLengthSum, mask) variantsCount := generatePermutations("", len(mask), blockLengs, blockLengthSum, mask)
match := 0 log.Printf("%d : for line %s blocks %+v matches %d\n", lineNum, mask, blockLengs, variantsCount)
for range variants { matches <- variantsCount
match += 1 wg.Done()
}(line, i)
} }
fmt.Printf("for line %s blocks %+v matches %d\n", mask, blockLengs, match)
num := 0
for match := range matches {
num += 1
result += match result += match
log.Printf("%d. intermediate: %d\n", num, result)
fmt.Printf("%d\n", result)
} }
end := time.Now()
diff := end.Sub(start)
log.Printf("> calculated for %s", diff.String())
return result return result
} }
@ -89,30 +115,30 @@ func ReadLine(line string) (string, []int) {
return mask, blockLengs return mask, blockLengs
} }
func generatePermutations(curString string, targetLength int, blockLengths []int, blockLengthsSum int, mask string) []string { func generatePermutations(curString string, targetLength int, blockLengths []int, blockLengthsSum int, mask string) int {
// fmt.Printf("> entering with \n%s\nfor map \n%s\n\n", curString, mask) // fmt.Printf("> entering with \n%s\nfor map \n%s\n\n", curString, mask)
// time.Sleep(time.Second) // time.Sleep(time.Second)
if !isVariantMatchesMask(curString, mask) { if !isVariantMatchesMask(curString, mask) {
return []string{} return 0
} }
// log.Printf("> entering with %s\n", curString) // log.Printf("> entering with %s\n", curString)
if len(blockLengths) == 0 { if len(blockLengths) == 0 {
if len(curString) > targetLength { if len(curString) > targetLength {
return []string{} return 0
} }
variant := curString + strings.Repeat(".", targetLength-len(curString)) variant := curString + strings.Repeat(".", targetLength-len(curString))
if !isVariantMatchesMask(variant, mask) { if !isVariantMatchesMask(variant, mask) {
return []string{} return 0
} }
return []string{variant} return 1
} }
nextBlock := blockLengths[0] nextBlock := blockLengths[0]
restBlocks := blockLengths[1:] restBlocks := blockLengths[1:]
if len(curString)+blockLengthsSum > targetLength { if len(curString) + blockLengthsSum + len(blockLengths) - 1 > targetLength {
return []string{} return 0
} }
isLast := len(restBlocks) == 0 isLast := len(restBlocks) == 0
@ -124,10 +150,10 @@ func generatePermutations(curString string, targetLength int, blockLengths []int
whenPass := curString + "." whenPass := curString + "."
whenAdd := curString + strings.Repeat("#", nextBlock) + strings.Repeat(".", rightPointRepeat) whenAdd := curString + strings.Repeat("#", nextBlock) + strings.Repeat(".", rightPointRepeat)
variantsWhenPass := generatePermutations(whenPass, targetLength, blockLengths, blockLengthsSum, mask) passCount := generatePermutations(whenPass, targetLength, blockLengths, blockLengthsSum, mask)
variantsWhenAdd := generatePermutations(whenAdd, targetLength, restBlocks, blockLengthsSum-nextBlock, mask) addCount := generatePermutations(whenAdd, targetLength, restBlocks, blockLengthsSum-nextBlock, mask)
return append(variantsWhenAdd, variantsWhenPass...) return passCount + addCount
} }
func isVariantMatchesMask(variant, mask string) bool { func isVariantMatchesMask(variant, mask string) bool {

View File

@ -92,3 +92,13 @@ for mask ???????#??.????####? and blocks [1 1 1 1 1 6]
...#.#.#.#.#.######. ...#.#.#.#.#.######.
...#.#.#.#.#..###### ...#.#.#.#.#..######
...#.#.#.#..#.###### ...#.#.#.#..#.######
* well, maybe overnight will calculate.
but i guess i needed to check whether blocks are 'always' taking full width
then i'll only need to calculate once, and then multiply
** for example
2023/12/12 20:40:41 699 : for line ??#?????#???.? ???#?????#???.????#?????#???.????#?????#???.????#?????#???.? blocks [3 1 2 1 3 1 2 1 3 1 2 1 3 1 2 1 3 1 2 1] matches 38294856
??#?? ???#?? ?.?
3,1,2,1 - 10+3 = 13
lowest s ###.#.##.#..... - plenty of space for additional