Report = Data.define(:levels) do def safe? deltas = levels.each_cons(2).map { _1 - _2 } (deltas.all?(&:negative?) || deltas.all?(&:positive?)) && (deltas.all? { (1..3).cover?(_1.abs) }) end def dampened return enum_for(__method__) unless block_given? (0...levels.length).each do |i| yield Report.new(levels[0...i] + levels[i+1..]) end end end input = DATA.readlines(chomp: true) .map { _1.scan(/\d+/).map(&:to_i) } .map { Report.new(_1) } # part one pp input.count(&:safe?) # part two pp input.count { _1.safe? || _1.dampened.any?(&:safe?) } __END__ 7 6 4 2 1 1 2 7 8 9 9 7 6 2 1 1 3 2 4 5 8 6 4 4 1 1 3 6 7 9