110 lines
2.4 KiB
Go
110 lines
2.4 KiB
Go
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
|
|
}
|