You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

119 lines
1.9 KiB
Go

package day8
import (
"math"
"regexp"
"gitea.paas.celticinfo.fr/oabrivard/aoc2023/utils"
)
type Step struct {
src string
left string
right string
}
func CountSteps(lines []string) int {
result := 0
steps := map[string]Step{}
directions := lines[0]
//matches occurrences like RFK = (DBD, FDM)
var re = regexp.MustCompile(`([A-Z]{3}?)\s*=\s*\(([A-Z]{3}?)\s*,\s*([A-Z]{3}?)\)`)
for i := 2; i < len(lines); i++ {
matches := re.FindStringSubmatch(lines[i])
src := matches[1]
left := matches[2]
right := matches[3]
steps[src] = Step{src, left, right}
}
loops := math.MaxInt32
step := steps["AAA"]
for {
for _, d := range directions {
result++
if d == 'L' {
step = steps[step.left]
} else {
step = steps[step.right]
}
if step.src == "ZZZ" {
return result
}
}
loops--
if loops == 0 {
break
}
}
return 0
}
func CountParallelSteps(lines []string) int {
steps := map[string]Step{}
threads := []Step{}
directions := lines[0]
//matches occurrences like RFK = (DBD, FDM)
var re = regexp.MustCompile(`([A-Z0-9]{3}?)\s*=\s*\(([A-Z0-9]{3}?)\s*,\s*([A-Z0-9]{3}?)\)`)
for i := 2; i < len(lines); i++ {
matches := re.FindStringSubmatch(lines[i])
src := matches[1]
left := matches[2]
right := matches[3]
step := Step{src, left, right}
steps[src] = step
if src[2] == 'A' {
threads = append(threads, step)
}
}
loops := math.MaxInt32
reachedZ := 0
countZ := make([]int, len(threads))
results := make([]int, len(threads))
for {
for _, d := range directions {
for i := range threads {
countZ[i]++
if d == 'L' {
threads[i] = steps[threads[i].left]
} else {
threads[i] = steps[threads[i].right]
}
if threads[i].src[2] == 'Z' && results[i] == 0 {
reachedZ++
results[i] = countZ[i]
}
}
if reachedZ == len(threads) {
return utils.LCM(results[0], results[1], results...)
}
}
loops--
if loops == 0 {
break
}
}
return 0
}