class IngredientManagement attr_reader :ranges, :ids def initialize(ranges, ids) @ranges = ranges @ids = ids end def self.for(input) ranges, ids = input.split("\n\n") new( ranges.split("\n").map{ |r| s, e = r.split("-").map(&:to_i); s..e }, ids.split("\n").map(&:to_i) ) end def fresh?(id) ranges.any? { |range| range.include? id } end def fresh_ingredient_ids ids.select { |id| fresh? id } end def all_fresh_ids # this makes it OOM! # return ranges.map(&:to_a).flatten.uniq [] end def all_fresh_ids_count combine_ranges.map(&:size).sum end def combine_two_ranges(r1, r2) return [r1, r2] if r2.begin > r1.end || r1.begin > r2.end [([r1.begin, r2.begin].min)..([r1.end, r2.end].max)] end def combine_ranges(rs = ranges) rs.sort_by!(&:begin) index = 0 while index < rs.length - 1 c2r = combine_two_ranges(rs[index], rs[index + 1]) if c2r.length == 2 # did not combine index += 1 else # combined rs.delete_at(index) rs.delete_at(index) rs.insert(index, c2r[0]) end end rs end end