Skip to content

Commit

Permalink
no solution for day 12 part 2. Will work on this later
Browse files Browse the repository at this point in the history
  • Loading branch information
devries committed Dec 13, 2023
1 parent 1e411f6 commit 467f454
Showing 1 changed file with 143 additions and 71 deletions.
214 changes: 143 additions & 71 deletions day12p2/solution.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ func Solve(r io.Reader) any {

numbers := strings.Split(parts[1], ",")

groups := make([]int64, len(numbers)*5)
groups := make([]int, len(numbers)*5)

for i, v := range numbers {
n, err := strconv.ParseInt(v, 10, 64)
n, err := strconv.Atoi(v)
utils.Check(err, "Unable to convert %s to int64", v)
for j := 0; j < 5; j++ {
groups[i+len(numbers)*j] = n
Expand All @@ -52,107 +52,179 @@ func Solve(r io.Reader) any {
return sum
}

func findValid(row []rune, groups []int64) int64 {
func findValid(row []rune, groups []int) int64 {
valids := int64(0)

for i, r := range row {
if r == '?' {
// replace with functional spring
trialA := make([]rune, len(row))
copy(trialA, row)
trialA[i] = '.'
if isValid(trialA, groups) {
valids += findValid(trialA, groups)
}

// replace with broken sprint
trialB := make([]rune, len(row))
copy(trialB, row)
trialB[i] = '#'
if isValid(trialB, groups) {
valids += findValid(trialB, groups)
}

return valids
}
if isCompleteAndValid(row, groups) {
valids = 1
return 1
}

if isValid(row, groups) {
valids = 1
// if utils.Verbose {
// fmt.Printf("\t%s\n", string(row))
// }
for _, r := range findNext(row, groups) {
valids += findValid(r, groups)
}

return valids
}

func isValid(row []rune, groups []int64) bool {
cgroups := []int64{}

n := int64(0)
sum := int64(0)
empties := int64(0)
firstEmpty := false
func findNext(row []rune, groups []int) [][]rune {
cgroups := []int{}
inGroup := false
ng := 0
firstQ := len(row)
ret := [][]rune{}
brokenSum := 0
unknownSum := 0

// To add:
// find minimum possible groups
// by checking for '.' between remaining '#'
// also: if !firstEmpty sum==sum(groups)

for _, r := range row {
// fmt.Println(string(row))
for i, r := range row {
switch r {
case '#':
n++
sum++
if i < firstQ {
inGroup = true
ng++
}
brokenSum++
case '.':
if !firstEmpty && n > 0 {
cgroups = append(cgroups, n)
n = 0
if i < firstQ {
inGroup = false
if ng > 0 {
cgroups = append(cgroups, ng)
ng = 0
}
}
case '?':
empties++
if !firstEmpty && n > 0 {
cgroups = append(cgroups, n)
if firstQ > i {
firstQ = i
}
n = 0
firstEmpty = true
unknownSum++
}
}
if !firstEmpty && n > 0 {
cgroups = append(cgroups, n)
if firstQ == len(row) {
return ret
}
n = 0

if !firstEmpty && len(cgroups) != len(groups) {
return false
// Check there are enough remainging to make all groups
remain := len(row) - firstQ
if inGroup {
remain += ng
}

needForGroupings := 0
for i := len(cgroups); i < len(groups); i++ {
needForGroupings += groups[i] + 1
}
needForGroupings--

if needForGroupings > remain {
return ret
}

sum := 0
for _, g := range groups {
sum += g
}

if brokenSum+unknownSum < sum {
// invalid
return ret
}

if len(cgroups) > len(groups) {
// more groups already made than allowed
return false
// invalid
return ret
}

totalBroken := int64(0)
cgl := len(cgroups)
for i, g := range groups {
if i < cgl-1 && cgroups[i] != g {
return false
} else if i == cgl-1 && cgroups[i] > g {
// What if there are no empties? then cgroups[i] should equal g
if len(cgroups) == len(groups) {
for i := firstQ; i < len(row); i++ {
if row[i] == '#' {
return ret
}
row[i] = '.'
}
ret = append(ret, row)
return ret
}

// Complete next group of broken springs
need := groups[len(cgroups)]
endPoint := len(row)
if inGroup {
// group must go here
need -= ng
endPoint = firstQ + 1
} else {
for i := firstQ + 1; i < len(row); i++ {
if row[i] == '#' {
endPoint = i + 1
break
}
}
}

if need+firstQ > len(row) {
// not enough room
return ret
}

outer:
for start := firstQ; start < endPoint; start++ {
newrow := make([]rune, len(row))
copy(newrow, row)
for i := firstQ; i < start; i++ {
newrow[i] = '.'
}
for i := start; i < need+start; i++ {
if i == len(newrow) || newrow[i] == '.' {
// wont work
continue outer
}
newrow[i] = '#'
}
if need+start < len(row) {
if row[need+start] == '#' {
// invalid
continue outer
}
newrow[need+start] = '.'
}
ret = append(ret, newrow)
}

return ret
}

func isCompleteAndValid(row []rune, groups []int) bool {
cgroups := []int{}
ng := 0

for _, r := range row {
switch r {
case '?':
return false
case '#':
ng++
case '.':
if ng > 0 {
cgroups = append(cgroups, ng)
ng = 0
}
}
totalBroken += g
}
if ng > 0 {
cgroups = append(cgroups, ng)
}

if sum > totalBroken {
// too many defects
if len(groups) != len(cgroups) {
return false
}

if sum+empties < totalBroken {
// not enough to make total broken
return false
for i, ng := range cgroups {
if ng != groups[i] {
return false
}
}

// fmt.Printf("\tValid: %s\n", string(row))
return true
}

0 comments on commit 467f454

Please sign in to comment.