57 lines
1.1 KiB
Ruby
57 lines
1.1 KiB
Ruby
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
|