diff --git a/cmd.go b/cmd.go deleted file mode 100644 index 17e7883..0000000 --- a/cmd.go +++ /dev/null @@ -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) -} diff --git a/day12/day12.go b/day12/day12.go index 0565234..803acf4 100644 --- a/day12/day12.go +++ b/day12/day12.go @@ -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) diff --git a/day12/day12_test.go b/day12/day12_test.go index 3942182..1cbaea8 100644 --- a/day12/day12_test.go +++ b/day12/day12_test.go @@ -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) } }