Completed part 2 of Day 12 puzzle with a lot of help to handle large expansion factor

main
oabrivard 2 years ago
parent e21e23d253
commit 23060cdf49

@ -1,16 +0,0 @@
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)
}

@ -8,11 +8,6 @@ import (
"gitea.paas.celticinfo.fr/oabrivard/aoc2023/utils"
)
func countArrangements(cond string, gs int) int {
return 0
}
func generateConditions(condPattern []byte) [][]byte {
result := [][]byte{}
@ -37,7 +32,7 @@ func generateConditions(condPattern []byte) [][]byte {
return result
}
func SumArragements(lines []string) int {
func SumArragements1(lines []string) int {
result := 0
for l, line := range lines {
@ -72,168 +67,113 @@ func SumArragements(lines []string) int {
return result
}
func SumArragements2(lines []string) int {
result := 0
var solved map[string]int
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(`\.+`)
/*
func CountArrangements(line []byte, gs []int, curr_gs int, previous byte, s string) int {
if curr_gs == len(gs)-1 && gs[curr_gs] == 0 {
for _, c := range line {
if c == '#' {
return 0
}
}
//fmt.Println(s)
return 1
}
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++
}
if len(line) == 0 {
return 0
}
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)
key := string(line) + fmt.Sprintf("%v-%v", gs, curr_gs)
val, found := solved[key]
if found {
return val
}
curr_gs++
count := 0
switch line[0] {
case '?':
line[0] = '.'
count1 := CountArrangements(line, gs, curr_gs, previous, s)
line[0] = '#'
count2 := CountArrangements(line, gs, curr_gs, previous, s)
line[0] = '?'
count = count1 + count2
case '#':
if previous == '.' || previous == 0 {
if curr_gs >= 0 && gs[curr_gs] > 0 {
return 0
}
curr_gs++
}
*/
result += count
}
if curr_gs >= len(gs) {
return 0
}
if gs[curr_gs] == 0 {
return 0
}
gs[curr_gs]--
count = CountArrangements(line[1:], gs, curr_gs, '#', s+"#")
gs[curr_gs]++
case '.':
count = CountArrangements(line[1:], gs, curr_gs, '.', s+".")
}
return result
}
solved[key] = count
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 {
return count
}
*/
func CountArrangements(conds []byte, gs []int) int {
if len(gs) == 0 {
for _, c := range conds {
if c == '#' {
return 0
}
}
//fmt.Println(s)
return 1
}
if len(line) == 0 {
if len(conds) == 0 {
return 0
}
key := fmt.Sprintf("%v-%v", conds, gs)
val, found := solved[key]
if found {
return val
}
count := 0
switch line[0] {
switch conds[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
conds[0] = '.'
count += CountArrangements(conds, gs)
conds[0] = '#'
count += CountArrangements(conds, gs)
conds[0] = '?'
case '#':
if previous == '.' || previous == 0 {
if curr_gs >= 0 && gs[curr_gs] > 0 {
return 0
first_gs := gs[0]
if first_gs <= len(conds) &&
!strings.Contains(string(conds[0:first_gs]), ".") {
if first_gs == len(conds) {
count = CountArrangements(conds[first_gs:], gs[1:])
} else if conds[first_gs] != '#' {
count = CountArrangements(conds[first_gs+1:], gs[1:])
}
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)
count = CountArrangements(conds[1:], gs)
}
/*
if !strings.Contains(string(line), "?") {
solved[string(line)+fmt.Sprintf("%v,%v", gs, curr_gs)] = count
}
*/
solved[key] = 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 {
func SumArragements2(lines []string, expansion int) int {
result := 0
for l, line := range lines {
@ -241,25 +181,25 @@ func SumArragements4(lines []string) int {
parsed_gs := utils.ParseIntArray(line_parts[1], ",") // group sizes
gs := []int{}
for k := 0; k < 5; k++ {
for i := 0; i < expansion+1; i++ {
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])
for i := 0; i < expansion; i++ {
sb.WriteString("?")
sb.WriteString(line_parts[0])
}
s := sb.String()
solved := map[string]int{}
solved = map[string]int{}
count := Count([]byte(s), gs, -1, 0, "", solved) // numberOfArrangements for the line
/*
count := CountArrangements([]byte(s), gs, -1, 0, "") // numberOfArrangements for the line
*/
count := CountArrangements([]byte(s), gs) // numberOfArrangements for the line
fmt.Printf("%d arrangements for %s on line %d\n", count, s, l)

@ -6,7 +6,7 @@ import (
"gitea.paas.celticinfo.fr/oabrivard/aoc2023/utils"
)
func TestSumArragements(t *testing.T) {
func TestSumArragements1(t *testing.T) {
lines := []string{
"???.### 1,1,3",
".??..??...?##. 1,1,3",
@ -16,17 +16,17 @@ func TestSumArragements(t *testing.T) {
"?###???????? 3,2,1",
}
result := SumArragements(lines)
result := SumArragements1(lines)
if result != 21 {
t.Fatalf("expected 21, got %v", result)
}
}
func TestSumArragementsWithInput(t *testing.T) {
func TestSumArragements1WithInput1(t *testing.T) {
lines := utils.ReadLines("input.txt")
result := SumArragements(lines)
result := SumArragements1(lines)
if result != 7110 {
t.Fatalf("expected 7110, got %v", result)
@ -34,23 +34,6 @@ func TestSumArragementsWithInput(t *testing.T) {
}
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",
@ -60,59 +43,31 @@ func TestSumArragements3(t *testing.T) {
"?###???????? 3,2,1",
}
result := SumArragements3(lines)
result := SumArragements2(lines, 0)
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)
result = SumArragements2(lines, 4)
if result != 525152 {
t.Fatalf("expected 525152, got %v", result)
}
}
func TestSumArragements4_2(t *testing.T) {
lines := []string{
"?#?##?#????.?..?? 9,1",
"????????#???#? 1,8",
}
func TestSumArragements2WithInput(t *testing.T) {
lines := utils.ReadLines("input.txt")
result := SumArragements4(lines)
result := SumArragements2(lines, 0)
if result != 525152 {
t.Fatalf("expected 525152, got %v", result)
if result != 7110 {
t.Fatalf("expected 7110, got %v", result)
}
}
func TestSumArragements4WithInput(t *testing.T) {
lines := utils.ReadLines("input.txt")
result := SumArragements4(lines)
result = SumArragements2(lines, 4)
if result != 525152 {
t.Fatalf("expected 525152, got %v", result)
if result != 1566786613613 {
t.Fatalf("expected 1566786613613, got %v", result)
}
}

Loading…
Cancel
Save