Files
advent-of-gode/2023/12/code.go
2023-12-14 17:55:47 +02:00

123 lines
2.4 KiB
Go

package main
import (
"strconv"
"strings"
"github.com/jpillora/puzzler/harness/aoc"
)
func main() {
aoc.Harness(run)
}
// on code change, run will be executed 4 times:
// 1. with: false (part1), and example input
// 2. with: true (part2), and example input
// 3. with: false (part1), and user input
// 4. with: true (part2), and user input
// the return value of each run is printed to stdout
func run(part2 bool, input string) any {
// when you're ready to do part 2, remove this "not implemented" block
if part2 {
return "not implemented"
}
// solve part 1 here
sum := 0
for _, l := range strings.Split(input, "\n") {
if l == "" {
continue
}
spl := strings.Split(l, " ")
combo := make([]int, 0)
for _, c := range strings.Split(spl[1], ",") {
ci, _ := strconv.Atoi(c)
combo = append(combo, ci)
}
//fmt.Printf("\nLooking in %v %v\n", spl[0], combo)
poss := iteratePossibilities(spl[0], combo)
//fmt.Printf("In %v %v: %v\n", spl[0], combo, poss)
sum += poss
}
return sum
}
func iteratePossibilities(springs string, combo []int) int {
if len(combo) == 0 {
panic("Combo is empty")
}
lenMatch := combo[0]
if len(springs) < lenMatch {
// Cannot match, not enough space
return 0
}
p := 0
for i := 0; i < len(springs)-lenMatch+1; i++ {
match := true
forceMatch := false
for m := i; m < i+lenMatch; m++ {
if rune(springs[m]) == '.' {
match = false
}
if rune(springs[m]) == '#' && i == m {
forceMatch = true
}
}
if !match {
// Keep trying
if forceMatch {
break
}
continue
}
matchFrom := i + lenMatch
if len(springs) > i+lenMatch {
if rune(springs[i+lenMatch]) == '#' {
// Would be contigious, does not work
if forceMatch {
break
}
continue
}
matchFrom += 1
}
// Cool! We are matched!
if len(combo) == 1 {
// Check, finally, that there are no possible # in the future (which would violate the requirements)
anyFuture := false
for j := matchFrom; j < len(springs); j++ {
if rune(springs[j]) == '#' {
anyFuture = true
}
}
if !anyFuture {
//fmt.Printf("MATCHED %v in %v from [%v;%v)\n", lenMatch, springs, i, i+lenMatch-1)
p += 1
}
} else {
//fmt.Printf("Matched %v in %v from [%v;%v)\n", lenMatch, springs, i, i+lenMatch-1)
p += iteratePossibilities(springs[matchFrom:], combo[1:])
}
if forceMatch {
break
}
}
return p
}