diff --git a/2018/ruby/day_17.rb b/2018/ruby/day_17.rb index 48235bf..41d1169 100644 --- a/2018/ruby/day_17.rb +++ b/2018/ruby/day_17.rb @@ -15,6 +15,8 @@ class Slice new(squares) end + attr_reader :squares + def initialize(squares) @squares = squares @squares[[500, 0]] = ?+ @@ -27,7 +29,6 @@ class Slice max_y = @squares.keys.map(&:last).max loop do - settled = [] @active.to_a.each do |pos| @active.delete(pos) x, y = pos @@ -36,38 +37,37 @@ class Slice @squares[[x, y+1]] = ?| @active << [x, y+1] when ?| + next if y+1 > max_y + if @squares[[x, y+1]].nil? - if y+1 <= max_y - @squares[[x, y+1]] = ?| - @active << [x, y+1] - end + @squares[[x, y+1]] = ?| + @active << [x, y+1] else - left = @squares[[x-1, y]].nil? - right = @squares[[x+1, y]].nil? - if !left && !right - settled << [x, y] - end - if left + if @squares[[x-1, y]].nil? @squares[[x-1, y]] = ?| @active << [x-1, y] end - if right + + if @squares[[x+1, y]].nil? @squares[[x+1, y]] = ?| @active << [x+1, y] end + + left_x = x-1 + left_x -= 1 until @squares[[left_x, y]] != ?| + right_x = x+1 + right_x += 1 until @squares[[right_x, y]] != ?| + if @squares[[left_x, y]] == ?# && @squares[[right_x, y]] == ?# + (left_x+1..right_x-1).each do |x| + @squares[[x, y]] = ?~ + @active << [x, y-1] if @squares[[x, y-1]] == ?| + end + 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 + return if @active.empty? yield self end @@ -139,7 +139,7 @@ class TestSlice < Minitest::Test ....#######... SLICE - 6.times { simulation.next } + 5.times { simulation.next } assert_equal <<~SLICE.chomp, @slice.to_s ......+....... ......|.....#. @@ -157,7 +157,7 @@ class TestSlice < Minitest::Test ....#######... SLICE - 5.times { simulation.next } + 4.times { simulation.next } assert_equal <<~SLICE.chomp, @slice.to_s ......+....... ......|.....#. @@ -175,7 +175,7 @@ class TestSlice < Minitest::Test ....#######... SLICE - 4.times { simulation.next } + 2.times { simulation.next } assert_equal <<~SLICE.chomp, @slice.to_s ......+....... ......|.....#. @@ -193,7 +193,7 @@ class TestSlice < Minitest::Test ....#######... SLICE - 24.times { simulation.next } + 21.times { simulation.next } assert_equal <<~SLICE.chomp, @slice.to_s ......+....... ......|.....#. @@ -234,6 +234,21 @@ class TestSlice < Minitest::Test end def solve(input) + slice = Slice.parse(input) + min_y = slice.squares.select {|_,s| s == ?# }.map(&:first).map(&:last).min + simulation = slice.simulate + + loop do + simulation.next + end + + # puts + # min_x, max_x = slice.water.map(&:first).minmax + # min_y, max_y = slice.water.map(&:last).minmax + # min_y = [0, min_y].min + # puts (min_y..max_y).map {|y| (min_x-1..max_x+1).map {|x| slice.squares.fetch([x, y]) { ?. } }.join }.join(?\n) + + slice.water.count {|_,y| y >= min_y } end if __FILE__ == $0