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
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
|
|
}
|