Reputation: 7486
Let's say I have two ranges (x1,x2) and (z1,z2). What is fastest way to check if they intersect?
if
#case: (2,4), (3,6)
x1 > z1 < x2 and (z2 < x1 or z2 > x2)
or
#case: (2,4) , (1,3)
x1 > z2 < x2 and (z1 < x1 or z1 > x2)
or
#case: (3,6), (2,4)
............. reverse(1) x <--> z
or
#case: (1,3), (2,4)
............. reverse(2) x <--> z
BTW containing one range in the other is OK, for example
(2,5) , (3,4)
(2,5) , (3,5)
(2,5) , (2,4)
(this makes the question not a duplicate. In addition the conditions are <, > rather than >=, <=. And one more I expect input ranges to be also unordered, for example (x2,x1),(z2,z1) ; (z1,z2),(x1,x2) )
But this, for example, does not count as intersection:
(2,5), (2,5)
What is a faster way with less checks?
NOT a duplicate ... here is the solution :
def olap(x1,x2,z1,z2):
if x1 == x2 or z1 == z2 : return True
if x1 == z1 and x2 == z2 : return True
if x1 > x2 : x1,x2 = x2,x1
if z1 > z2 : z1,z2 = z2,z1
if x1 > z1 or x2 > z2 : z1,z2,x1,x2 = x1,x2,z1,z2
return x1 < z1 < x2 and (z2 < x1 or z2 > x2)
Upvotes: 1
Views: 143
Reputation: 31597
Simplest check is to verify a property of intersecting intervals: None of the leftmost endpoints (smaller) can be higher than a rightmost endpoint (higher).
x1 x2
a ------------ if x1 > y2: a would be to the right of b
b ---------------- if y1 > x2: b would be to the right of a
y1 y2
def overlap(x1, x2, y1, y2):
""" Overlap means neither of the intervals
is "to the right or left" of the other.
"""
return x1 <= y2 and y1 <= x2
Upvotes: 1