From 3a43f904311562419c9150863b4385cd76d09482 Mon Sep 17 00:00:00 2001 From: efim Date: Tue, 12 Dec 2023 15:05:09 +0000 Subject: [PATCH] day12, example --- day12/dayTwelve.go | 124 +++++++++++++++++++++++++++++++++++++++++++++ day12/example | 6 +++ day12/example1 | 6 +++ day12/notes.org | 8 +++ main.go | 6 +-- 5 files changed, 147 insertions(+), 3 deletions(-) create mode 100644 day12/dayTwelve.go create mode 100644 day12/example create mode 100644 day12/example1 create mode 100644 day12/notes.org diff --git a/day12/dayTwelve.go b/day12/dayTwelve.go new file mode 100644 index 0000000..7b12bbd --- /dev/null +++ b/day12/dayTwelve.go @@ -0,0 +1,124 @@ +package day12 + +import ( + "fmt" + "log" + "os" + "strconv" + "strings" +) + +func Run() int { + fmt.Println("hello day 12.") + + filename := "day12/example1" + bytes, err := os.ReadFile(filename) + if err != nil { + panic(fmt.Sprintf("error reading file %s\n", filename)) + } + + sum := 0 + text := string(bytes) + text = strings.TrimSpace(text) + + for _, line := range strings.Split(text, "\n") { + mask, blockLengs := ReadLine(line) + + blockLengthSum := 0 + for _, blockLen := range blockLengs { + blockLengthSum += blockLen + } + + variants := generatePermutations("", len(mask), blockLengs, blockLengthSum) + + match := 0 + for _, variant := range variants { + if isVariantMatchesMask(variant, mask) { + match += 1 + } + } + log.Printf("for line %s matches %d\n", mask, match) + sum += match + } + + // totalVariants := 0 + // for _, variang := range test1 { + // totalVariants += 1 + // if isVariantMatchesMask(variang, line3) { + // match += 1 + // fmt.Print("matches: ") + // } + // fmt.Println(variang) + // } + // fmt.Printf("total variants : %d\n", totalVariants) + return sum +} + +// ???.### 1,1,3 +func ReadLine(line string) (string, []int) { + firstSplit := strings.Split(line, " ") + if len(firstSplit) != 2 { + panic(fmt.Sprintf("error splitting %s into 2", line)) + } + mask := firstSplit[0] + blockLengthStrings := strings.Split(firstSplit[1], ",") + blockLengs := make([]int, len(blockLengthStrings)) + + for i, blockLenStr := range blockLengthStrings { + num, err := strconv.Atoi(blockLenStr) + if err != nil { + panic(fmt.Sprintf("error extracting num %s from %s\n", blockLenStr, line)) + } + blockLengs[i] = num + } + + return mask, blockLengs +} + +func generatePermutations(curString string, targetLength int, blockLengths []int, blockLengthsSum int) []string { + // log.Printf("> entering with %s\n", curString) + if len(blockLengths) == 0 { + if len(curString) > targetLength { + return []string{} + } + variant := curString + strings.Repeat(".", targetLength - len(curString)) + return []string{variant} + } + + nextBlock := blockLengths[0] + restBlocks := blockLengths[1:] + + if len(curString) + blockLengthsSum > targetLength { + return []string{} + } + + isLast := len(restBlocks) == 0 + rightPointRepeat := 1 + if isLast { + rightPointRepeat = 0 } + + whenPass := curString + "." + whenAdd := curString + strings.Repeat("#", nextBlock) + strings.Repeat(".", rightPointRepeat) + + variantsWhenPass := generatePermutations(whenPass, targetLength, blockLengths, blockLengthsSum) + variantsWhenAdd := generatePermutations(whenAdd, targetLength, restBlocks, blockLengthsSum - nextBlock) + + return append(variantsWhenAdd, variantsWhenPass...) +} + +func isVariantMatchesMask(variant, mask string) bool { + if len(mask) < len(variant) { + log.Printf("mask %s is less than variant %s\n", mask, variant) + } + maskRunes := []rune(mask) + for i, symb := range variant { + if maskRunes[i] == '?' { + continue + } + if maskRunes[i] != symb { + return false + } + } + + return true +} diff --git a/day12/example b/day12/example new file mode 100644 index 0000000..e2bdf5e --- /dev/null +++ b/day12/example @@ -0,0 +1,6 @@ +#.#.### 1,1,3 +.#...#....###. 1,1,3 +.#.###.#.###### 1,3,1,6 +####.#...#... 4,1,1 +#....######..#####. 1,6,5 +.###.##....# 3,2,1 diff --git a/day12/example1 b/day12/example1 new file mode 100644 index 0000000..e925935 --- /dev/null +++ b/day12/example1 @@ -0,0 +1,6 @@ +???.### 1,1,3 +.??..??...?##. 1,1,3 +?#?#?#?#?#?#?#? 1,3,1,6 +????.#...#... 4,1,1 +????.######..#####. 1,6,5 +?###???????? 3,2,1 diff --git a/day12/notes.org b/day12/notes.org new file mode 100644 index 0000000..548b593 --- /dev/null +++ b/day12/notes.org @@ -0,0 +1,8 @@ +#+title: Notes +* i guess let's generate all possible? and short circuit when they are not matching mask +how do i generate all possible? + +i take length of the mask, that's max size +then for each step, either put . or put n # from the input. + +add to current string, and do 2 recursive calls, one with diminished 'queue', one with same diff --git a/main.go b/main.go index c9768ea..364c5b6 100644 --- a/main.go +++ b/main.go @@ -3,12 +3,12 @@ package main import ( "log" - "sunshine.industries/aoc2023/day11" + "sunshine.industries/aoc2023/day12" ) func main() { log.Print("> starting run:") - result := day11.Run() - log.Printf("day11 result: %d\n****\n", result) + result := day12.Run() + log.Printf("day12 result: %d\n****\n", result) }