@@ -294,22 +294,24 @@ defmodule Range do
294294 iex> Range.disjoint?(1..10//2, 2..10//2)
295295 true
296296
297- # First element in common in all below is 29
298- iex> Range.disjoint?(2..100//3, 9..100//5)
299- false
300- iex> Range.disjoint?(101..2//-3, 99..9//-5)
301- false
297+ # First element in common is 29
302298 iex> Range.disjoint?(1..100//14, 8..100//21)
303299 false
304300 iex> Range.disjoint?(57..-1//-14, 8..100//21)
305301 false
306- iex> Range.disjoint?(1..100//14, 51 ..8//-21)
302+ iex> Range.disjoint?(1..100//14, 50 ..8//-21)
307303 false
308-
309- # If 29 is out of range
310304 iex> Range.disjoint?(1..28//14, 8..28//21)
311305 true
306+
307+ # First element in common is 14
312308 iex> Range.disjoint?(2..28//3, 9..28//5)
309+ false
310+ iex> Range.disjoint?(26..2//-3, 29..9//-5)
311+ false
312+
313+ # Starting from the back without alignment
314+ iex> Range.disjoint?(27..11//-3, 30..0//-7)
313315 true
314316
315317 """
@@ -334,21 +336,28 @@ defmodule Range do
334336 # progressions and see if they belong within the ranges
335337 # https://math.stackexchange.com/questions/1656120/formula-to-find-the-first-intersection-of-two-arithmetic-progressions
336338 { gcd , u , v } = Integer . extended_gcd ( - step1 , step2 )
337- c = first1 - first2 + step2 - step1
338- t1 = - c / step1 * u
339- t2 = - c / step2 * v
340- t = max ( floor ( t1 ) + 1 , floor ( t2 ) + 1 )
341- x = div ( c * u + t * step2 , gcd ) - 1
342- y = div ( c * v + t * step1 , gcd ) - 1
343-
344- x < 0 or first1 + x * step1 > last1 or
345- y < 0 or first2 + y * step2 > last2
339+
340+ if rem ( first2 - first1 , gcd ) == 0 do
341+ c = first1 - first2 + step2 - step1
342+ t1 = - c / step2 * u
343+ t2 = - c / step1 * v
344+ t = max ( floor ( t1 ) + 1 , floor ( t2 ) + 1 )
345+ x = div ( c * u + t * step2 , gcd ) - 1
346+ y = div ( c * v + t * step1 , gcd ) - 1
347+
348+ x < 0 or first1 + x * step1 > last1 or
349+ y < 0 or first2 + y * step2 > last2
350+ else
351+ true
352+ end
346353 end
347354 end
348355 end
349356
350357 @ compile inline: [ normalize: 3 ]
351- defp normalize ( first , last , step ) when first > last , do: { last , first , - step }
358+ defp normalize ( first , last , step ) when first > last ,
359+ do: { first - abs ( div ( first - last , step ) * step ) , first , - step }
360+
352361 defp normalize ( first , last , step ) , do: { first , last , step }
353362
354363 @ doc false
0 commit comments