Completed part 1 of Day 12 puzzle
parent
75cb2d755d
commit
e21e23d253
@ -0,0 +1,16 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gitea.paas.celticinfo.fr/oabrivard/aoc2023/day12"
|
||||
"gitea.paas.celticinfo.fr/oabrivard/aoc2023/utils"
|
||||
)
|
||||
|
||||
func main() {
|
||||
lines := utils.ReadLines("day12/input.txt")
|
||||
|
||||
result := day12.SumArragements4(lines)
|
||||
|
||||
fmt.Println(result)
|
||||
}
|
||||
@ -0,0 +1,270 @@
|
||||
package day12
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"gitea.paas.celticinfo.fr/oabrivard/aoc2023/utils"
|
||||
)
|
||||
|
||||
func countArrangements(cond string, gs int) int {
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func generateConditions(condPattern []byte) [][]byte {
|
||||
result := [][]byte{}
|
||||
|
||||
for i, b := range condPattern {
|
||||
if b == '?' {
|
||||
newPattern1 := make([]byte, len(condPattern))
|
||||
copy(newPattern1, condPattern)
|
||||
newPattern1[i] = '.'
|
||||
result = append(result, generateConditions(newPattern1)...)
|
||||
|
||||
newPattern2 := make([]byte, len(condPattern))
|
||||
copy(newPattern2, condPattern)
|
||||
newPattern2[i] = '#'
|
||||
result = append(result, generateConditions(newPattern2)...)
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
result = append(result, condPattern)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func SumArragements(lines []string) int {
|
||||
result := 0
|
||||
|
||||
for l, line := range lines {
|
||||
line_parts := strings.Fields(line)
|
||||
gs := utils.ParseIntArray(line_parts[1], ",") // group sizes
|
||||
count := 0 // numberOfArrangements for the line
|
||||
|
||||
var sb strings.Builder
|
||||
sb.WriteString(`^\.*`)
|
||||
for i, curr_gs := range gs {
|
||||
sb.WriteString(fmt.Sprintf("#{%d}?", curr_gs))
|
||||
|
||||
if i != len(gs)-1 {
|
||||
sb.WriteString(`\.+`)
|
||||
}
|
||||
}
|
||||
sb.WriteString(`\.*$`)
|
||||
reString := sb.String()
|
||||
|
||||
var re = regexp.MustCompile(reString)
|
||||
conds := generateConditions([]byte(line_parts[0]))
|
||||
for _, cond := range conds {
|
||||
if re.Match(cond) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("Matching line %d : %d\n", l, count)
|
||||
result += count
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func SumArragements2(lines []string) int {
|
||||
result := 0
|
||||
|
||||
for l, line := range lines {
|
||||
line_parts := strings.Fields(line)
|
||||
//conds := line_parts[0] //utils.SplitNoBlank(line_parts[0], ".") // conditions
|
||||
parsed_gs := utils.ParseIntArray(line_parts[1], ",") // group sizes
|
||||
count := 0 // numberOfArrangements for the line
|
||||
//curr_gs := 0
|
||||
|
||||
gs := []int{}
|
||||
for k := 0; k < 5; k++ {
|
||||
gs = append(gs, parsed_gs...)
|
||||
}
|
||||
|
||||
var sb strings.Builder
|
||||
sb.WriteString(`^\.*`)
|
||||
for i, curr_gs := range gs {
|
||||
sb.WriteString(fmt.Sprintf("#{%d}?", curr_gs))
|
||||
|
||||
if i != len(gs)-1 {
|
||||
sb.WriteString(`\.+`)
|
||||
}
|
||||
}
|
||||
sb.WriteString(`\.*$`)
|
||||
reString := sb.String()
|
||||
|
||||
//fmt.Println(conds, gs)
|
||||
|
||||
var re = regexp.MustCompile(reString)
|
||||
fmt.Println(reString)
|
||||
|
||||
var sb2 strings.Builder
|
||||
sb2.WriteString(line_parts[0])
|
||||
sb2.WriteString("?")
|
||||
sb2.WriteString(line_parts[0])
|
||||
sb2.WriteString("?")
|
||||
sb2.WriteString(line_parts[0])
|
||||
sb2.WriteString("?")
|
||||
sb2.WriteString(line_parts[0])
|
||||
sb2.WriteString("?")
|
||||
sb2.WriteString(line_parts[0])
|
||||
|
||||
s := sb2.String()
|
||||
|
||||
conds := generateConditions([]byte(s))
|
||||
for _, cond := range conds {
|
||||
if re.Match(cond) {
|
||||
fmt.Printf("Matching line %d - %s : ", l, string(cond))
|
||||
fmt.Print("ok")
|
||||
fmt.Println("")
|
||||
count++
|
||||
}
|
||||
}
|
||||
fmt.Printf("Matching line %d : %d\n", l, count)
|
||||
/*
|
||||
for j, cond := range conds {
|
||||
// compter les ? consécutifs (?count)
|
||||
|
||||
// sum des curr_gs
|
||||
// si blanc alors arrangement des
|
||||
// peek prochain char = ? > curr_gs alors on splitte avant prochain_char
|
||||
|
||||
if j == len(conds)-1 {
|
||||
// last condition
|
||||
} else {
|
||||
// not the last condition
|
||||
c := countArrangements(cond, gs[curr_gs])
|
||||
count += c
|
||||
|
||||
fmt.Printf("%d arrangements for part %s of line %d\n", c, cond, i)
|
||||
|
||||
curr_gs++
|
||||
}
|
||||
}
|
||||
*/
|
||||
result += count
|
||||
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func Count(line []byte, gs []int, curr_gs int, previous byte, s string, solved map[string]int) int {
|
||||
/*
|
||||
val, found := solved[string(line)+fmt.Sprintf("%v,%v", gs, curr_gs)]
|
||||
if found {
|
||||
return val
|
||||
}
|
||||
*/
|
||||
if curr_gs == len(gs)-1 && gs[curr_gs] == 0 {
|
||||
for _, c := range line {
|
||||
if c == '#' {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
//fmt.Println(s)
|
||||
return 1
|
||||
}
|
||||
|
||||
if len(line) == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
count := 0
|
||||
switch line[0] {
|
||||
case '?':
|
||||
line[0] = '.'
|
||||
count1 := Count(line, gs, curr_gs, previous, s, solved)
|
||||
line[0] = '#'
|
||||
count2 := Count(line, gs, curr_gs, previous, s, solved)
|
||||
line[0] = '?'
|
||||
count = count1 + count2
|
||||
case '#':
|
||||
if previous == '.' || previous == 0 {
|
||||
if curr_gs >= 0 && gs[curr_gs] > 0 {
|
||||
return 0
|
||||
}
|
||||
curr_gs++
|
||||
}
|
||||
if curr_gs >= len(gs) {
|
||||
return 0
|
||||
}
|
||||
if gs[curr_gs] == 0 {
|
||||
return 0
|
||||
}
|
||||
gs[curr_gs]--
|
||||
count = Count(line[1:], gs, curr_gs, '#', s+"#", solved)
|
||||
gs[curr_gs]++
|
||||
case '.':
|
||||
count = Count(line[1:], gs, curr_gs, '.', s+".", solved)
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
if !strings.Contains(string(line), "?") {
|
||||
solved[string(line)+fmt.Sprintf("%v,%v", gs, curr_gs)] = count
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
return count
|
||||
}
|
||||
|
||||
func SumArragements3(lines []string) int {
|
||||
result := 0
|
||||
|
||||
for l, line := range lines {
|
||||
line_parts := strings.Fields(line)
|
||||
gs := utils.ParseIntArray(line_parts[1], ",") // group sizes
|
||||
solved := map[string]int{}
|
||||
count := Count([]byte(line_parts[0]), gs, -1, 0, "", solved) // numberOfArrangements for the line
|
||||
|
||||
fmt.Printf("%d arrangements for %s on line %d\n", count, line_parts[0], l)
|
||||
|
||||
result += count
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func SumArragements4(lines []string) int {
|
||||
result := 0
|
||||
|
||||
for l, line := range lines {
|
||||
line_parts := strings.Fields(line)
|
||||
parsed_gs := utils.ParseIntArray(line_parts[1], ",") // group sizes
|
||||
|
||||
gs := []int{}
|
||||
for k := 0; k < 5; k++ {
|
||||
gs = append(gs, parsed_gs...)
|
||||
}
|
||||
|
||||
var sb strings.Builder
|
||||
sb.WriteString(line_parts[0])
|
||||
sb.WriteString("?")
|
||||
sb.WriteString(line_parts[0])
|
||||
sb.WriteString("?")
|
||||
sb.WriteString(line_parts[0])
|
||||
sb.WriteString("?")
|
||||
sb.WriteString(line_parts[0])
|
||||
sb.WriteString("?")
|
||||
sb.WriteString(line_parts[0])
|
||||
|
||||
s := sb.String()
|
||||
solved := map[string]int{}
|
||||
|
||||
count := Count([]byte(s), gs, -1, 0, "", solved) // numberOfArrangements for the line
|
||||
|
||||
fmt.Printf("%d arrangements for %s on line %d\n", count, s, l)
|
||||
|
||||
result += count
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
@ -0,0 +1,118 @@
|
||||
package day12
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"gitea.paas.celticinfo.fr/oabrivard/aoc2023/utils"
|
||||
)
|
||||
|
||||
func TestSumArragements(t *testing.T) {
|
||||
lines := []string{
|
||||
"???.### 1,1,3",
|
||||
".??..??...?##. 1,1,3",
|
||||
"?#?#?#?#?#?#?#? 1,3,1,6",
|
||||
"????.#...#... 4,1,1",
|
||||
"????.######..#####. 1,6,5",
|
||||
"?###???????? 3,2,1",
|
||||
}
|
||||
|
||||
result := SumArragements(lines)
|
||||
|
||||
if result != 21 {
|
||||
t.Fatalf("expected 21, got %v", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSumArragementsWithInput(t *testing.T) {
|
||||
lines := utils.ReadLines("input.txt")
|
||||
|
||||
result := SumArragements(lines)
|
||||
|
||||
if result != 7110 {
|
||||
t.Fatalf("expected 7110, got %v", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSumArragements2(t *testing.T) {
|
||||
lines := []string{
|
||||
// "???.### 1,1,3",
|
||||
".??..??...?##. 1,1,3",
|
||||
// "?#?#?#?#?#?#?#? 1,3,1,6",
|
||||
// "????.#...#... 4,1,1",
|
||||
// "????.######..#####. 1,6,5",
|
||||
// "?###???????? 3,2,1",
|
||||
}
|
||||
|
||||
result := SumArragements2(lines)
|
||||
|
||||
if result != 21 {
|
||||
t.Fatalf("expected 21, got %v", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSumArragements3(t *testing.T) {
|
||||
lines := []string{
|
||||
"???.### 1,1,3",
|
||||
".??..??...?##. 1,1,3",
|
||||
"?#?#?#?#?#?#?#? 1,3,1,6",
|
||||
"????.#...#... 4,1,1",
|
||||
"????.######..#####. 1,6,5",
|
||||
"?###???????? 3,2,1",
|
||||
}
|
||||
|
||||
result := SumArragements3(lines)
|
||||
|
||||
if result != 21 {
|
||||
t.Fatalf("expected 21, got %v", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSumArragements3WithInput(t *testing.T) {
|
||||
lines := utils.ReadLines("input.txt")
|
||||
|
||||
result := SumArragements3(lines)
|
||||
|
||||
if result != 7110 {
|
||||
t.Fatalf("expected 7110, got %v", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSumArragements4(t *testing.T) {
|
||||
lines := []string{
|
||||
"???.### 1,1,3",
|
||||
".??..??...?##. 1,1,3",
|
||||
"?#?#?#?#?#?#?#? 1,3,1,6",
|
||||
"????.#...#... 4,1,1",
|
||||
"????.######..#####. 1,6,5",
|
||||
"?###???????? 3,2,1",
|
||||
}
|
||||
|
||||
result := SumArragements4(lines)
|
||||
|
||||
if result != 525152 {
|
||||
t.Fatalf("expected 525152, got %v", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSumArragements4_2(t *testing.T) {
|
||||
lines := []string{
|
||||
"?#?##?#????.?..?? 9,1",
|
||||
"????????#???#? 1,8",
|
||||
}
|
||||
|
||||
result := SumArragements4(lines)
|
||||
|
||||
if result != 525152 {
|
||||
t.Fatalf("expected 525152, got %v", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSumArragements4WithInput(t *testing.T) {
|
||||
lines := utils.ReadLines("input.txt")
|
||||
|
||||
result := SumArragements4(lines)
|
||||
|
||||
if result != 525152 {
|
||||
t.Fatalf("expected 525152, got %v", result)
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue