Initial data commit
This commit is contained in:
parent
72d218235f
commit
f23f22d71c
199087 changed files with 3378941 additions and 0 deletions
84
Task/Multiplicative-order/Nim/multiplicative-order.nim
Normal file
84
Task/Multiplicative-order/Nim/multiplicative-order.nim
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
import strformat
|
||||
import bignum
|
||||
|
||||
type PExp = tuple[prime: Int; exp: uint]
|
||||
|
||||
let
|
||||
one = newInt(1)
|
||||
two = newInt(2)
|
||||
ten = newInt(10)
|
||||
|
||||
|
||||
func sqrt(n: Int): Int =
|
||||
var s = n
|
||||
while true:
|
||||
result = s
|
||||
s = (n div result + result) shr 1
|
||||
if s >= result: break
|
||||
|
||||
|
||||
proc factor(n: Int): seq[PExp] =
|
||||
var n = n
|
||||
var e = 0u
|
||||
while n.bit(e) == 0: inc e
|
||||
if e != 0:
|
||||
n = n shr e
|
||||
result.add (two, e)
|
||||
var s = sqrt(n)
|
||||
var d = newInt(3)
|
||||
while n > one:
|
||||
if d > s: d = n
|
||||
e = 0u
|
||||
while true:
|
||||
let (q, r) = divMod(n, d)
|
||||
if not r.isZero: break
|
||||
n = q
|
||||
inc e
|
||||
if e != 0:
|
||||
result.add (d.clone, e)
|
||||
s = sqrt(n)
|
||||
inc d, two
|
||||
|
||||
|
||||
proc moBachShallit58(a, n: Int; pf: seq[PExp]): Int =
|
||||
let n = abs(n)
|
||||
let n1 = n - one
|
||||
result = newInt(1)
|
||||
for pe in pf:
|
||||
let y = n1 div pe.prime.pow(pe.exp)
|
||||
var o = 0u
|
||||
var x = a.exp(y.toInt.uint, n)
|
||||
while x > one:
|
||||
x = x.exp(pe.prime.toInt.uint, n)
|
||||
inc o
|
||||
var o1 = pe.prime.pow(o)
|
||||
o1 = o1 div gcd(result, o1)
|
||||
result *= o1
|
||||
|
||||
|
||||
proc moTest(a, n: Int) =
|
||||
if n.probablyPrime(25) == 0:
|
||||
echo "Not computed. Modulus must be prime for this algorithm."
|
||||
return
|
||||
|
||||
stdout.write if a.bitLen < 100: &"ord({a})" else: "ord([big])"
|
||||
stdout.write if n.bitlen < 100: &" mod {n}" else: " mod [big]"
|
||||
let mob = moBachShallit58(a, n, factor(n - one))
|
||||
echo &" = {mob}"
|
||||
|
||||
|
||||
when isMainModule:
|
||||
moTest(newInt(37), newInt(3343))
|
||||
|
||||
var b = ten.pow(100) + one
|
||||
motest(b, newInt(7919))
|
||||
|
||||
b = ten.pow(1000) + one
|
||||
moTest(b, newInt("15485863"))
|
||||
|
||||
b = ten.pow(10000) - one
|
||||
moTest(b, newInt("22801763489"))
|
||||
|
||||
moTest(newInt("1511678068"), newInt("7379191741"))
|
||||
|
||||
moTest(newInt("3047753288"), newInt("2257683301"))
|
||||
Loading…
Add table
Add a link
Reference in a new issue