[2018][ruby][17.1] settling and overflow
diff --git a/2018/ruby/day_17.rb b/2018/ruby/day_17.rb
index 3c2ff1b..68fec69 100644
--- a/2018/ruby/day_17.rb
+++ b/2018/ruby/day_17.rb
@@ -24,16 +24,48 @@ class Slice
def simulate
return enum_for(__method__) unless block_given?
+ max_y = @squares.keys.map(&:last).max
+
loop do
- @active.to_a.each do |x, y|
- @active.delete([x, y])
- case @squares.fetch([x, y])
+ settled = []
+ @active.to_a.each do |pos|
+ @active.delete(pos)
+ x, y = pos
+ case @squares.fetch(pos)
when ?+
@squares[[x, y+1]] = ?|
@active << [x, y+1]
when ?|
- @squares[[x, y+1]] = ?|
- @active << [x, y+1]
+ if @squares[[x, y+1]].nil?
+ if y+1 <= max_y
+ @squares[[x, y+1]] = ?|
+ @active << [x, y+1]
+ end
+ else
+ left = @squares[[x-1, y]].nil?
+ right = @squares[[x+1, y]].nil?
+ if !left && !right
+ settled << [x, y]
+ end
+ if left
+ @squares[[x-1, y]] = ?|
+ @active << [x-1, y]
+ end
+ if right
+ @squares[[x+1, y]] = ?|
+ @active << [x+1, y]
+ end
+ end
+ end
+ end
+
+ if @active.empty?
+ while pos = settled.shift
+ @squares[pos] = ?~ if @squares[pos] == ?|
+ x, y = pos
+ @active << [x, y-1] if @squares[[x, y-1]] == ?|
+ settled << [x-1, y] if @squares[[x-1, y]] == ?|
+ settled << [x+1, y] if @squares[[x+1, y]] == ?|
end
end
@@ -89,7 +121,6 @@ class TestSlice < Minitest::Test
simulation = @slice.simulate
slice = 5.times { simulation.next }
-
assert_equal <<~SLICE.chomp, @slice.to_s
......+.......
......|.....#.
@@ -106,6 +137,96 @@ class TestSlice < Minitest::Test
....#.....#...
....#######...
SLICE
+
+ slice = 6.times { simulation.next }
+ assert_equal <<~SLICE.chomp, @slice.to_s
+ ......+.......
+ ......|.....#.
+ .#..#.|.....#.
+ .#..#.|#......
+ .#..#.|#......
+ .#....|#......
+ .#~~~~~#......
+ .#######......
+ ..............
+ ..............
+ ....#.....#...
+ ....#.....#...
+ ....#.....#...
+ ....#######...
+ SLICE
+
+ slice = 5.times { simulation.next }
+ assert_equal <<~SLICE.chomp, @slice.to_s
+ ......+.......
+ ......|.....#.
+ .#..#.|.....#.
+ .#..#.|#......
+ .#..#.|#......
+ .#~~~~~#......
+ .#~~~~~#......
+ .#######......
+ ..............
+ ..............
+ ....#.....#...
+ ....#.....#...
+ ....#.....#...
+ ....#######...
+ SLICE
+
+ slice = 4.times { simulation.next }
+ assert_equal <<~SLICE.chomp, @slice.to_s
+ ......+.......
+ ......|.....#.
+ .#..#.|.....#.
+ .#..#~~#......
+ .#..#~~#......
+ .#~~~~~#......
+ .#~~~~~#......
+ .#######......
+ ..............
+ ..............
+ ....#.....#...
+ ....#.....#...
+ ....#.....#...
+ ....#######...
+ SLICE
+
+ slice = 24.times { simulation.next }
+ assert_equal <<~SLICE.chomp, @slice.to_s
+ ......+.......
+ ......|.....#.
+ .#..#||||...#.
+ .#..#~~#|.....
+ .#..#~~#|.....
+ .#~~~~~#|.....
+ .#~~~~~#|.....
+ .#######|.....
+ ........|.....
+ ........|.....
+ ....#~~~~~#...
+ ....#~~~~~#...
+ ....#~~~~~#...
+ ....#######...
+ SLICE
+
+ slice = 9.times { simulation.next }
+ assert_equal <<~SLICE.chomp, @slice.to_s
+ ......+.......
+ ......|.....#.
+ .#..#||||...#.
+ .#..#~~#|.....
+ .#..#~~#|.....
+ .#~~~~~#|.....
+ .#~~~~~#|.....
+ .#######|.....
+ ........|.....
+ ...|||||||||..
+ ...|#~~~~~#|..
+ ...|#~~~~~#|..
+ ...|#~~~~~#|..
+ ...|#######|..
+ SLICE
end
end