exact_division.sf 898 B

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. #!/usr/bin/ruby
  2. # Daniel "Trizen" Șuteu
  3. # Date: 18 May 2020
  4. # https://github.com/trizen
  5. # Algorithm for performing exact division of two large integers, using the Chinese Remainder Theorem (CRT).
  6. func exact_division(n,k) {
  7. return n if (k == 1)
  8. return 1 if (n == k)
  9. var nv = n.valuation(2)
  10. var kv = k.valuation(2)
  11. n >>= nv
  12. k >>= kv
  13. return (1 << (nv-kv)) if (n == k)
  14. var lcm = 2
  15. var crt = [1, 2]
  16. var logk = k.ilog2
  17. var logn = n.ilog2-1
  18. for(var p = 3; true ; p.next_prime!) {
  19. var q = Math.chinese(crt, [invmod(k, p) * (n%p), p]) || next
  20. crt = [q, lcm *= p]
  21. if (q.ilog2 + logk >= logn) {
  22. break if (q*k >= n)
  23. }
  24. }
  25. crt[0] << (nv - kv)
  26. }
  27. say exact_division(43*97, 43)
  28. say exact_division(100!, 50!)
  29. with (10!) {|n|
  30. n.divisors.each {|d|
  31. assert_eq(exact_division(n, d), n/d)
  32. }
  33. }