Commit bd78e6af authored by Lin Jen-Shin's avatar Lin Jen-Shin

Use algorithm from Kamil:

Excluding sorting, this is O(n) which should be much faster and
much simpler and easier to understand.
parent 031b1623
...@@ -37,41 +37,22 @@ module Gitlab ...@@ -37,41 +37,22 @@ module Gitlab
if segments.empty? if segments.empty?
segments segments
else else
segments[1..-1].inject([segments.first]) do |current, target| segments.drop(1).inject([segments.first]) do |result, current|
left, result = insert_segment(current, target) merged = try_merge_segment(result.last, current)
if left # left is the latest one if merged
result << left result[-1] = merged
else
result result
else
result << current
end end
end end
end end
end end
def insert_segment(segments, init) def try_merge_segment(previous, current)
segments.inject([init, []]) do |target_result, member| if current.first <= previous.last
target, result = target_result Segment.new(previous.first, [previous.last, current.last].max)
if target.nil? # done
result << member
[nil, result]
elsif merged = try_merge_segment(target, member) # overlapped
[merged, result] # merge and keep finding the hole
elsif target.last < member.first # found the hole
result << target << member
[nil, result]
else
result << member
target_result
end
end
end
def try_merge_segment(target, member)
if target.first <= member.last && target.last >= member.first
Segment.new([target.first, member.first].min,
[target.last, member.last].max)
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment