2023 Day 12 Complete!
This commit is contained in:
109
2023/day12/main.go
Normal file
109
2023/day12/main.go
Normal file
@@ -0,0 +1,109 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
h "git.bullercodeworks.com/brian/adventofcode/helpers"
|
||||
)
|
||||
|
||||
func main() {
|
||||
inp := h.StdinToStringSlice()
|
||||
part1(inp)
|
||||
fmt.Println()
|
||||
part2(inp)
|
||||
}
|
||||
|
||||
func part1(input []string) {
|
||||
var records []string
|
||||
var groups [][]int
|
||||
for _, ln := range input {
|
||||
pts := strings.Fields(ln)
|
||||
records = append(records, pts[0])
|
||||
var grp []int
|
||||
for _, n := range strings.Split(pts[1], ",") {
|
||||
grp = append(grp, h.Atoi(n))
|
||||
}
|
||||
groups = append(groups, grp)
|
||||
}
|
||||
var result int
|
||||
for i := range records {
|
||||
// Initialize cache for this row
|
||||
cache := make(map[string]int)
|
||||
|
||||
// And solve the row
|
||||
result += solveRow(0, 0, records[i], groups[i], cache)
|
||||
}
|
||||
|
||||
fmt.Println("# Part 1")
|
||||
fmt.Println(result)
|
||||
}
|
||||
|
||||
func part2(input []string) {
|
||||
var records []string
|
||||
var groups [][]int
|
||||
for _, ln := range input {
|
||||
pts := strings.Fields(ln)
|
||||
// Unfold the paper
|
||||
pts[0] = fmt.Sprintf("%s?%s?%s?%s?%s", pts[0], pts[0], pts[0], pts[0], pts[0])
|
||||
pts[1] = fmt.Sprintf("%s,%s,%s,%s,%s", pts[1], pts[1], pts[1], pts[1], pts[1])
|
||||
records = append(records, pts[0])
|
||||
var grp []int
|
||||
for _, n := range strings.Split(pts[1], ",") {
|
||||
grp = append(grp, h.Atoi(n))
|
||||
}
|
||||
groups = append(groups, grp)
|
||||
}
|
||||
|
||||
var result int
|
||||
for i := range records {
|
||||
// Initialize cache for this row
|
||||
cache := make(map[string]int)
|
||||
|
||||
// And solve the row
|
||||
result += solveRow(0, 0, records[i], groups[i], cache)
|
||||
}
|
||||
|
||||
fmt.Println("# Part 2")
|
||||
fmt.Println(result)
|
||||
}
|
||||
|
||||
func ck(i, j int) string { return fmt.Sprintf("%d_%d", i, j) }
|
||||
|
||||
func solveRow(rbIdx, groupIdx int, record string, group []int, cache map[string]int) int {
|
||||
if rbIdx >= len(record) {
|
||||
if groupIdx < len(group) {
|
||||
return 0
|
||||
}
|
||||
return 1
|
||||
}
|
||||
if v, ok := cache[ck(rbIdx, groupIdx)]; ok {
|
||||
return v
|
||||
}
|
||||
res := 0
|
||||
if record[rbIdx] == '.' {
|
||||
res = solveRow(rbIdx+1, groupIdx, record, group, cache)
|
||||
} else {
|
||||
if record[rbIdx] == '?' {
|
||||
res += solveRow(rbIdx+1, groupIdx, record, group, cache)
|
||||
}
|
||||
if groupIdx < len(group) {
|
||||
count := 0
|
||||
for k := rbIdx; k < len(record); k++ {
|
||||
if count > group[groupIdx] || record[k] == '.' || count == group[groupIdx] && record[k] == '?' {
|
||||
break
|
||||
}
|
||||
count += 1
|
||||
}
|
||||
if count == group[groupIdx] {
|
||||
if rbIdx+count < len(record) && record[rbIdx+count] != '#' {
|
||||
res += solveRow(rbIdx+count+1, groupIdx+1, record, group, cache)
|
||||
} else {
|
||||
res += solveRow(rbIdx+count, groupIdx+1, record, group, cache)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
cache[ck(rbIdx, groupIdx)] = res
|
||||
return res
|
||||
}
|
||||
Reference in New Issue
Block a user