#!/usr/bin/env ruby result = File.readlines("2.input").map(&:split).map { _1.map(&:to_i) } .select do |v| (v == v.sort || v == v.sort.reverse) && v.each_cons(2).map { _1.sort.inject(:-).abs }.all? { 1 <= _1 && _1 <= 3 } end.size puts result require "rspec/autorun" class Report < Array def self.from_line(line) new(line.split.map(&:to_i)) end def safe? (increasing? || decreasing?) && within_limit? end def safe_with_dampener? dampened.any?(&:safe?) end private def dampened size.times.map { Report.new(except(_1)) } end def except(v) reject.with_index { |_, i| i == v } end def increasing? self == sort end def decreasing? self == sort.reverse end def within_limit? each_cons(2) .map { _1.sort.inject(:-).abs } .all? { 1 <= _1 && _1 <= 3 } end end input = File.readlines("2.input") puts "2-1" puts input .map { Report.from_line(_1) } .select(&:safe?) .size puts "2-2" puts input .map { Report.from_line(_1) } .select(&:safe_with_dampener?) .size describe Report do [ "48 51 52 53 52", "86 87 88 91 91", "22 25 28 31 32 36", "65 66 68 69 71 72 75 82" ].each do |line| it "returns safe? as false for #{line}" do expect(Report.from_line(line).safe?).to eq(false) end end [ "1 2 3 4 5 6 7", "1 3 5 7 9", "9 8 7", "1 4 5 8" ].each do |line| it "returns safe? as true for #{line}" do expect(Report.from_line(line).safe?).to eq(true) end end end