Skip to content

Commit bd88671

Browse files
committed
Refactor Day 11 and Puzzle 2
1 parent 4e70bc4 commit bd88671

File tree

2 files changed

+52
-29
lines changed

2 files changed

+52
-29
lines changed

β€Žlib/solutions/day_11.rbβ€Ž

Lines changed: 52 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,66 @@
11
class Day11
2-
attr_accessor :stones, :blinks
2+
attr_accessor :stones, :iterations, :cache
3+
4+
# Notes:
5+
# - Keeping input as String is faster when splitting, only convert to int when needed
6+
# - Caching is key
7+
# - Count, don't keep resulting stone values in memory.
8+
9+
def initialize
10+
@cache = {}
11+
end
312

413
def part_one(input)
5-
@stones = input.split(' ').map(&:to_i)
14+
run(input, 25)
15+
end
16+
17+
def part_two(input)
18+
run(input, 75)
19+
end
620

7-
25.times { blink! }
21+
def run(input, iterations)
22+
@stones = input.split(' ')
23+
@iterations = iterations
824

9-
@stones.size
25+
result = 0
26+
@stones.each { |s| result += count_stones_after(s, iterations) }
27+
result
1028
end
1129

12-
def blink!
13-
new_stones = []
14-
@stones.each_with_index do |stone, i|
15-
value_s = stone.to_s
30+
def count_stones_after(stone, iterations)
31+
return 1 if iterations == 0
1632

17-
if stone == 0
18-
new_stones[i] = 1
19-
elsif value_s.length.even?
20-
split = value_s.length / 2
21-
new_stones[i] = [value_s[0...split].to_i, value_s[split..-1].to_i]
22-
else
23-
new_stones[i] = stone * 2024
24-
end
25-
end
26-
27-
@stones = new_stones.flatten!
33+
cache_key = [stone, iterations].freeze
34+
return @cache[cache_key] if @cache.key?(cache_key)
35+
36+
next_iter = blink(stone)
37+
38+
total = 0
39+
next_iter.each { |s| total += count_stones_after(s, iterations - 1) }
40+
@cache[cache_key] = total
41+
total
2842
end
2943

30-
def part_two(input)
31-
@stones = input.split(' ').map(&:to_i)
44+
def blink(stone)
45+
if stone == '0'
46+
['1']
47+
elsif stone.size.even?
48+
split_digits(stone)
49+
else
50+
[multiply(stone, 2024)]
51+
end
52+
end
3253

33-
75.times { blink! }
54+
def multiply(stone, factor)
55+
(stone.to_i * factor).to_s
56+
end
3457

35-
@stones.size
58+
def split_digits(stone)
59+
split = stone.size / 2
60+
left = stone[0...split].sub(/^0+/, '') # Remove leading zeros on left half
61+
left = '0' if left.empty?
62+
right = stone[split..-1].sub(/^0+/, '') # Remove leading zeros on right half
63+
right = '0' if right.empty?
64+
[left, right]
3665
end
3766
end

β€Žspec/solutions/day_11_spec.rbβ€Ž

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,4 @@
99
expect(subject.part_one(input)).to eq(55_312)
1010
end
1111
end
12-
13-
describe '#part_two' do
14-
it 'calculates the correct solutions for part two' do
15-
expect(subject.part_two(input)).to eq(0)
16-
end
17-
end
1812
end

0 commit comments

Comments
Β (0)