1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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__