An algorithm for combining overlapping intervals:
1. Sort the intervals on start time
2. Assign left and right of first interval (0)
3. Iterate over the intervals from 1 to size-1
if (current interval start lies in prev. interval)
update right to max(prev. right, current. right)
else
[left, right] is non-overlapping interval => push it to answer array
reassign left and right to current interval
4. push last [left, right] to answer array
Decision:
availabilities = {
monday: [
{ start_time: 6,
end_time: 12 },
{ start_time: 8,
end_time: 18 }
],
tuesday: [
{ start_time: 10,
end_time: 16 },
{ start_time: 18,
end_time: 23 }
]
}
def solve(list)
return_hash = {}
list.each do |key, arr|
intervals = []
arr.each { |hash| intervals << [hash[:start_time], hash[:end_time]] }
non_overlapping_intervals = merge_interval(intervals)
temp = []
non_overlapping_intervals.each { |interval| temp << {start_time: interval[0], end_time: interval[1]} }
return_hash[key] = temp
end
return_hash
end
def merge_interval(v)
intervals = []
v.sort()
size = v.size()
l, r = v[0][0], v[0][1]
(1...size).each do |i|
if v[i][0] <= r
r = [r,v[i][1]].max;
else
intervals << [l, r]
l, r = v[i][0], v[i][1]
end
end
intervals << [l, r]
return intervals
end
p solve(availabilities)
Output:
{
:monday=>[{:start_time=>6, :end_time=>18}],
:tuesday=>[{:start_time=>10, :end_time=>16},
{:start_time=>18, :end_time=>23}]
}
source
share