tags:

views:

176

answers:

4

This is hopefully a very simple maths question. If I have two number ranges, what is the simplest and most efficient way to check if they clash, eg:

10-20 and 11-14 // clash as B is contained in A
11-15 and 20-22 // don't clash
24-26 and 20-30 // clash as A is contained in B
15-25 and 20-30 // clash as they overlap at each end

I currently have this mess, but there must be a much simpler way to do this check:

$clash = ($b1 >= $a1 && $b1 <= $a2)
    || ($b2 >= $a1 && $b2 <= $a2)
    || ($a1 >= $b1 && $a1 <= $b2)
    || ($a2 >= $b1 && $a2 <= $b2);
+2  A: 

The ranges DO NOT clash if and only if $a2 <= $b1 or $a1 >= $b2 (assuming that ranges are given as ordered pairs). Now negate the condition.

quant_dev
What if $a1 >= $b2? Doesn't clash then either.
Matthew Scharley
We're also assuming it is always the case that $a1 < $a2 and $b1 < $b2.
jeffamaphone
@Matthew: Right@jeffamaphone: Well, that's what you mean by a "range", isn't it?
quant_dev
I have edited my answer to reflect your illustrious comments.
quant_dev
+8  A: 

Well, first make sure you have well-ordered pairs (probably a good idea anyway, depending on what you plan to do with them):

if($a1 > $a2) {
    // swap $a1 and $a2
    $temp = $a1;
    $a1 = $a2;
    $a2 = $temp;
}
if($b1 > $b2) {
    // swap $b1 and $b2
    $temp = $b1;
    $b1 = $b2;
    $b2 = $temp;
}

Then you should be able to simplify to:

$clash = ($a2 <= $b1) || ($a1 >= $b2);

Edit: Whoops, got that test backwards! Try:

$clash = !(($a2 <= $b1) || ($a1 >= $b2));
Daniel Pryden
I was just going to post that :-) +1 for being faster.
Eric J.
sth
Thanks, that's great.
Jack Sleight
Single line method of swapping the variables, without the need for a $temp..."list($a2,$a1) = array($a1,$a2);"
scragar
+4  A: 

I think it should be as simple as this:

clash = A_LOW <= B_HIGH AND A_HIGH >= B_LOW
phantombrain
A: 

What you're looking for is the intersection of the arrays. http://us3.php.net/array_intersect

Basically,

$intersect = array_intersect($arr1, $arr2);
$clash = (count($intersect) > 0);

If any elements are in both $arr1 and $arr2, then $intersect will list those values. The count() call returns 1 (or more), so doing > 0 gives you if $arr1 and $arr2 have any similar elements.

davethegr8