@@ -294,22 +294,24 @@ defmodule Range do
294
294
iex> Range.disjoint?(1..10//2, 2..10//2)
295
295
true
296
296
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
302
298
iex> Range.disjoint?(1..100//14, 8..100//21)
303
299
false
304
300
iex> Range.disjoint?(57..-1//-14, 8..100//21)
305
301
false
306
- iex> Range.disjoint?(1..100//14, 51 ..8//-21)
302
+ iex> Range.disjoint?(1..100//14, 50 ..8//-21)
307
303
false
308
-
309
- # If 29 is out of range
310
304
iex> Range.disjoint?(1..28//14, 8..28//21)
311
305
true
306
+
307
+ # First element in common is 14
312
308
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)
313
315
true
314
316
315
317
"""
@@ -334,21 +336,28 @@ defmodule Range do
334
336
# progressions and see if they belong within the ranges
335
337
# https://math.stackexchange.com/questions/1656120/formula-to-find-the-first-intersection-of-two-arithmetic-progressions
336
338
{ 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
346
353
end
347
354
end
348
355
end
349
356
350
357
@ 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
+
352
361
defp normalize ( first , last , step ) , do: { first , last , step }
353
362
354
363
@ doc false
0 commit comments