-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexact_division.sf
46 lines (33 loc) · 898 Bytes
/
exact_division.sf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#!/usr/bin/ruby
# Daniel "Trizen" Șuteu
# Date: 18 May 2020
# https://github.com/trizen
# Algorithm for performing exact division of two large integers, using the Chinese Remainder Theorem (CRT).
func exact_division(n,k) {
return n if (k == 1)
return 1 if (n == k)
var nv = n.valuation(2)
var kv = k.valuation(2)
n >>= nv
k >>= kv
return (1 << (nv-kv)) if (n == k)
var lcm = 2
var crt = [1, 2]
var logk = k.ilog2
var logn = n.ilog2-1
for(var p = 3; true ; p.next_prime!) {
var q = Math.chinese(crt, [invmod(k, p) * (n%p), p]) || next
crt = [q, lcm *= p]
if (q.ilog2 + logk >= logn) {
break if (q*k >= n)
}
}
crt[0] << (nv - kv)
}
say exact_division(43*97, 43)
say exact_division(100!, 50!)
with (10!) {|n|
n.divisors.each {|d|
assert_eq(exact_division(n, d), n/d)
}
}