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