day12, example

This commit is contained in:
efim 2023-12-12 15:05:09 +00:00
parent 7032666476
commit 3a43f90431
5 changed files with 147 additions and 3 deletions

124
day12/dayTwelve.go Normal file
View File

@ -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
}

6
day12/example Normal file
View File

@ -0,0 +1,6 @@
#.#.### 1,1,3
.#...#....###. 1,1,3
.#.###.#.###### 1,3,1,6
####.#...#... 4,1,1
#....######..#####. 1,6,5
.###.##....# 3,2,1

6
day12/example1 Normal file
View File

@ -0,0 +1,6 @@
???.### 1,1,3
.??..??...?##. 1,1,3
?#?#?#?#?#?#?#? 1,3,1,6
????.#...#... 4,1,1
????.######..#####. 1,6,5
?###???????? 3,2,1

8
day12/notes.org Normal file
View File

@ -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

View File

@ -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)
}