mirror of
https://github.com/Crocmagnon/advent-of-code.git
synced 2025-01-02 19:21:56 +01:00
solve day8 part 2
This commit is contained in:
parent
4978707252
commit
7117aca07e
3 changed files with 70 additions and 5 deletions
|
@ -44,11 +44,66 @@ func move(current string, step int, leftRight string, nodes map[string][2]string
|
||||||
|
|
||||||
func Day08Part2(input io.Reader) (int, error) {
|
func Day08Part2(input io.Reader) (int, error) {
|
||||||
scanner := bufio.NewScanner(input)
|
scanner := bufio.NewScanner(input)
|
||||||
|
scanner.Scan()
|
||||||
|
leftRight := scanner.Text()
|
||||||
|
|
||||||
|
scanner.Scan() // skip blank line
|
||||||
|
|
||||||
|
nodes := make(map[string][2]string)
|
||||||
|
var positions []string
|
||||||
|
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
line := scanner.Text()
|
line := strings.Split(scanner.Text(), " = ") // AAA = (BBB, CCC)
|
||||||
_ = line
|
node := line[0]
|
||||||
|
rest := strings.Split(strings.NewReplacer("(", "", " ", "", ")", "").Replace(line[1]), ",")
|
||||||
|
nodes[node] = [2]string{rest[0], rest[1]}
|
||||||
|
if strings.HasSuffix(node, "A") {
|
||||||
|
positions = append(positions, node)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0, nil
|
step := 0
|
||||||
|
reachedZ := make([]int, len(positions))
|
||||||
|
for !allFinished(positions, reachedZ, step) {
|
||||||
|
for i := 0; i < len(positions); i++ {
|
||||||
|
positions[i] = move(positions[i], step, leftRight, nodes)
|
||||||
|
}
|
||||||
|
step++
|
||||||
|
}
|
||||||
|
|
||||||
|
return LCM(reachedZ[0], reachedZ[1], reachedZ[2:]...), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func allFinished(positions []string, reachedZ []int, step int) bool {
|
||||||
|
for i, pos := range positions {
|
||||||
|
if strings.HasSuffix(pos, "Z") && reachedZ[i] == 0 {
|
||||||
|
reachedZ[i] = step
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, z := range reachedZ {
|
||||||
|
if z == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// GCD and LCM from https://siongui.github.io/2017/06/03/go-find-lcm-by-gcd/
|
||||||
|
func GCD(a, b int) int {
|
||||||
|
for b != 0 {
|
||||||
|
t := b
|
||||||
|
b = a % b
|
||||||
|
a = t
|
||||||
|
}
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
func LCM(a, b int, integers ...int) int {
|
||||||
|
result := a * b / GCD(a, b)
|
||||||
|
|
||||||
|
for i := 0; i < len(integers); i++ {
|
||||||
|
result = LCM(result, integers[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,8 @@ func TestDay08Part1(t *testing.T) {
|
||||||
|
|
||||||
func TestDay08Part2(t *testing.T) {
|
func TestDay08Part2(t *testing.T) {
|
||||||
tests := []testCase{
|
tests := []testCase{
|
||||||
{"inputs/day08_test2", 0},
|
{"inputs/day08_test3", 6},
|
||||||
{"inputs/day08", 0},
|
{"inputs/day08", 14265111103729},
|
||||||
}
|
}
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.filename, check(test, Day08Part2))
|
t.Run(test.filename, check(test, Day08Part2))
|
||||||
|
|
10
2023/inputs/day08_test3
Normal file
10
2023/inputs/day08_test3
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
LR
|
||||||
|
|
||||||
|
11A = (11B, XXX)
|
||||||
|
11B = (XXX, 11Z)
|
||||||
|
11Z = (11B, XXX)
|
||||||
|
22A = (22B, XXX)
|
||||||
|
22B = (22C, 22C)
|
||||||
|
22C = (22Z, 22Z)
|
||||||
|
22Z = (22B, 22B)
|
||||||
|
XXX = (XXX, XXX)
|
Loading…
Reference in a new issue