From 4129a82f2695c5020e00118ce20884017eff6634 Mon Sep 17 00:00:00 2001 From: Alpha Chen Date: Tue, 13 Dec 2022 22:20:09 -0800 Subject: [PATCH] [2022][ruby][14.x] refactored --- 2022/ruby/day_14.rb | 64 +++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 37 deletions(-) diff --git a/2022/ruby/day_14.rb b/2022/ruby/day_14.rb index 55d3c87..23bb08f 100644 --- a/2022/ruby/day_14.rb +++ b/2022/ruby/day_14.rb @@ -12,51 +12,41 @@ cave = scan.each.with_object({}) {|line, cave| } } -x_min, x_max = cave.keys.map(&:first).minmax -y_min, y_max = cave.keys.map(&:last).minmax +def cave.to_s + x_min, x_max = keys.map(&:first).minmax + y_min, y_max = keys.map(&:last).minmax -inspect_cave = -> { - puts (0..y_max+1).map {|y| + (0..y_max+1).map {|y| (x_min-1..x_max+1).map {|x| - cave[[x, y]] || ?. + self.fetch([x, y], ?.) }.join }.join("\n") -} - -# part one -# sands = 0 -# loop do -# inspect_cave.() -# sands += 1 +end -# pos = [500, 0] -# while next_pos = [0, -1, 1].map {|dx| pos.zip([dx, 1]).map { _1 + _2 }}.find { cave[_1].nil? } -# pos = next_pos -# break if pos[1] >= y_max -# end -# break if pos[1] >= y_max +def pour_sand(cave, stop:) + return enum_for(__method__, cave, stop:) unless block_given? -# cave[pos] = ?o -# end + loop do + # puts cave + pos = [500, 0] -# inspect_cave.() -# p sands-1 + while next_pos = [0, -1, 1].map {|dx| pos.zip([dx, 1]).map { _1 + _2 }}.find { cave[_1].nil? } + pos = next_pos + break if stop.(*pos) + end + break if stop.(*pos) -# part two -cave.default_proc = ->(h,(x,y)) { h[[x, y]] = y == y_max + 2 ? ?# : nil } -sands = 0 -loop do - # inspect_cave.() - sands += 1 - - pos = [500, 0] - while next_pos = [0, -1, 1].map {|dx| pos.zip([dx, 1]).map { _1 + _2 }}.find { cave[_1].nil? } - pos = next_pos + cave[pos] = ?o + yield pos end - break if pos == [500, 0] - - cave[pos] = ?o end -inspect_cave.() -p sands +y_max = cave.keys.map(&:last).max + +# part one +p pour_sand(cave, stop: ->(_, y) { y >= y_max }).count + +# part two +cave.delete_if { _2 == ?o } # reset cave +cave.default_proc = ->(_,(_,y)) { y == y_max + 2 ? ?# : nil } +p pour_sand(cave, stop: ->(x, y) { [x, y] == [500, 0] }).count + 1