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 }