92 lines
1.5 KiB
Go
92 lines
1.5 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
h "git.bullercodeworks.com/brian/adventofcode/helpers"
|
|
)
|
|
|
|
func main() {
|
|
inp := h.StdinToStringSlice()
|
|
part1(inp)
|
|
fmt.Println()
|
|
part2(inp)
|
|
}
|
|
|
|
type node struct {
|
|
left, right string
|
|
}
|
|
|
|
func build(input []string) (string, map[string]node) {
|
|
inst := input[0]
|
|
input = input[2:]
|
|
m := make(map[string]node)
|
|
for i := range input {
|
|
var name, l, r string
|
|
fmt.Sscanf(input[i], "%s = (%3s, %3s)", &name, &l, &r)
|
|
m[name] = node{left: l, right: r}
|
|
}
|
|
return inst, m
|
|
}
|
|
|
|
func part1(input []string) {
|
|
inst, m := build(input)
|
|
curr := "AAA"
|
|
instIdx := 0
|
|
for curr != "ZZZ" {
|
|
switch inst[instIdx%len(inst)] {
|
|
case 'L':
|
|
curr = m[curr].left
|
|
case 'R':
|
|
curr = m[curr].right
|
|
}
|
|
instIdx++
|
|
}
|
|
fmt.Println("# Part 1")
|
|
fmt.Println(instIdx)
|
|
}
|
|
|
|
func part2(input []string) {
|
|
inst, m := build(input)
|
|
// Find all starting nodes
|
|
var starts []string
|
|
for k := range m {
|
|
if k[2] == 'A' {
|
|
starts = append(starts, k)
|
|
}
|
|
}
|
|
var dists []int
|
|
// Find the distances from 'starts' to the end nodes
|
|
for _, v := range starts {
|
|
cnt := 0
|
|
distMap := make(map[string]int)
|
|
// find the path to a 'Z'
|
|
for {
|
|
if v[2] == 'Z' {
|
|
// Found it
|
|
key := fmt.Sprintf("%s-%d", v, cnt%len(inst))
|
|
if distMap[key] == 1 {
|
|
break
|
|
}
|
|
distMap[key] = 1
|
|
dists = append(dists, cnt)
|
|
}
|
|
switch inst[cnt%len(inst)] {
|
|
case 'L':
|
|
v = m[v].left
|
|
case 'R':
|
|
v = m[v].right
|
|
}
|
|
cnt++
|
|
}
|
|
}
|
|
|
|
cnt := 1
|
|
for _, n := range dists {
|
|
cnt = h.Lcm(cnt, n)
|
|
}
|
|
|
|
fmt.Println("# Part 2")
|
|
fmt.Println(cnt)
|
|
}
|