Skip to content

Commit caab329

Browse files
author
Robb Kidd
committed
day 8, part 2
1 parent e1d012b commit caab329

File tree

1 file changed

+65
-20
lines changed

1 file changed

+65
-20
lines changed

2023/ruby/day08.rb

Lines changed: 65 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,41 +4,73 @@ class Day08 < Day # >
44

55
# @example
66
# day.part1 #=> 2
7+
# @example with cycles
8+
# day = Day08.new(SIX_STEPS_INPUT)
9+
# day.part1 #=> 6
710
def part1
8-
parse(input)
11+
instructions, network = parse(input)
912
steps = 0
10-
node = "AAA"
11-
@instructions
13+
current_node = "AAA"
14+
instructions
1215
.cycle do |instruction|
13-
break if node == "ZZZ"
16+
break if current_node == "ZZZ"
1417
steps += 1
15-
node = @network[node][instruction]
18+
current_node = network[current_node][instruction]
1619
end
1720
steps
1821
end
1922

2023
# @example
21-
# day.part2 #=> 'how are you'
24+
# day = Day08.new(PART2_EXAMPLE_INPUT)
25+
# day.part2 #=> 6
2226
def part2
23-
end
27+
instructions, network = parse(input)
28+
steps = 0
29+
start_nodes = network.keys.select { |node| node[-1] == "A" }
2430

25-
# @example
26-
# inst, net = day.parse(EXAMPLE_INPUT)
27-
# inst #=> ["R", "L"]
28-
def parse(input)
29-
stanzas = input.split("\n\n")
31+
start_nodes
32+
.map { |current_node|
33+
Thread.new { # for whatever multitasking Ruby will give me
34+
steps = 0
35+
a_to_z = nil
36+
37+
instructions
38+
.cycle do |instruction|
39+
if current_node[-1] == "Z" # on a Z node
40+
!a_to_z ? a_to_z = steps : break # note how many steps to the first Z node, stop on second Z node
41+
end
3042

31-
@instructions = stanzas[0].chars
43+
steps += 1
44+
current_node = network[current_node][instruction]
45+
end
3246

33-
@network = {}
34-
stanzas[1]
35-
.each_line
36-
.map { |line| line.scan(/\w+/) }
37-
.each { |node, left, right|
38-
@network[node] = { "L" => left, "R" => right }
47+
if (steps - a_to_z) != a_to_z
48+
raise("steps from Z-to-Z must match A-to-Z to use least common multiple")
49+
end
50+
a_to_z
51+
}
3952
}
53+
.map(&:value)
54+
.reduce(1, :lcm)
55+
end
4056

41-
[@instructions, @network]
57+
# @example
58+
# instructions, network = day.parse(EXAMPLE_INPUT)
59+
# instructions #=> ["R", "L"]
60+
# network["AAA"] #=> {"L" => "BBB", "R" => "CCC"}
61+
def parse(input)
62+
@stanzas ||= input.split("\n\n")
63+
64+
@parsed ||=
65+
[
66+
@stanzas[0].chars,
67+
@stanzas[1]
68+
.each_line
69+
.map { |line| line.scan(/\w+/) }
70+
.each_with_object({}) { |(node, left, right), network|
71+
network[node] = { "L" => left, "R" => right }
72+
}
73+
]
4274
end
4375

4476
EXAMPLE_INPUT = <<~INPUT
@@ -60,4 +92,17 @@ def parse(input)
6092
BBB = (AAA, ZZZ)
6193
ZZZ = (ZZZ, ZZZ)
6294
INPUT
95+
96+
PART2_EXAMPLE_INPUT = <<~INPUT
97+
LR
98+
99+
11A = (11B, XXX)
100+
11B = (XXX, 11Z)
101+
11Z = (11B, XXX)
102+
22A = (22B, XXX)
103+
22B = (22C, 22C)
104+
22C = (22Z, 22Z)
105+
22Z = (22B, 22B)
106+
XXX = (XXX, XXX)
107+
INPUT
63108
end

0 commit comments

Comments
 (0)