September 2017 Update

This commit is contained in:
Ingy döt Net 2017-09-23 10:01:46 +02:00
parent bba7bfd280
commit ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions

View file

@ -21,7 +21,7 @@ sub mo-prime($a, $p, $e) {
my $t = ($p - 1) * ($p ** ($e - 1)); # = Phi($p**$e) where $p prime
my @qs = 1;
for factor($t) -> $f {
@qs = @qs.map(-> $q { (0..$f.value).map(-> $j { $q * $f.key ** $j }) });
@qs = flat @qs.map(-> $q { (0..$f.value).map(-> $j { $q * $f.key ** $j }) });
}
@qs.sort();
@ -30,15 +30,13 @@ sub mo-prime($a, $p, $e) {
sub mo($a, $m) {
$a gcd $m == 1 || die "$a and $m are not relatively prime";
[lcm] 1, factor($m).map(-> $r { mo-prime($a, $r.key, $r.value) });
[lcm] flat 1, factor($m).map(-> $r { mo-prime($a, $r.key, $r.value) });
}
sub MAIN("test") {
use Test;
for (10, 21, 25, 150, 1231, 123141, 34131) -> $n {
# say factor($n).perl;
# say factor($n).map(-> $pair { $pair.key ** $pair.value }).perl;
is ([*] factor($n).map(-> $pair { $pair.key ** $pair.value })), $n, "$n factors correctly";
}

View file

@ -0,0 +1,26 @@
/*REXX pgm computes multiplicative order of a minimum integer N such that a^n mod m≡1*/
wa=0; wm=0 /* ═a═ ══m══ */ /*maximum widths of the A and M values.*/
@.=.; @.1= 3 10
@.2= 37 1000
@.3= 37 10000
@.4= 37 3343
@.5= 37 3344
@.6= 2 1000
pad=left('',9)
d=100 /*use 100 decimal digits for a starter.*/
do w=1 for 2 /*when W≡1, find max widths of A and M.*/
do j=1 while @.j\==.; parse var @.j a . 1 r m , n
if w==1 then do; wa=max(wa, length(a)); wm=max(wm, length(m)); iterate; end
if m//a==0 then n= ' [solution not possible]' /*test co-prime for A and B. */
numeric digits d /*start with 100 decimal digits. */
if n=='' then do n=2; p=r*a /*compute product──may have an exponent*/
parse var p 'E' _ /*try to extract the exponent from P. */
if _\=='' then do; numeric digits _+d /*bump the decimal digs.*/
p=r*a /*recalculate integer P.*/
end
if p//m==1 then leave /*now, perform the nitty-gritty modulo.*/
r=p /*assign product to R for next mult. */
end /*n*/ /* [↑] // is really ÷ remainder.*/
say pad 'a=' right(a,wa) pad "m=" right(m,wm) pad 'multiplicative order:' n
end /*j*/
end /*w*/ /*stick a fork in it, we're all done. */

View file

@ -0,0 +1,35 @@
var BN =Import("zklBigNum");
var Sieve=Import("sieve");
// factor n into powers of primes
// eg 9090 == 2^1 * 3^2 * 5^1 * 101^1
fcn factor2PP(n){ // lazy factors using lazy primes --> (prime,power) ...
Utils.Generator(fcn(a){
primes:=Utils.Generator(Sieve.postponed_sieve);
foreach p in (primes){
e:=0; while(a%p == 0){ a /= p; e+=1; }
if (e) vm.yield(p,e);
if (a<p*p) break;
}
if (a>1) vm.yield(a,1);
},n)
}
fcn _multOrdr1(a,p,e){
m:=p.pow(e);
t:=m/p*(p - 1);
qs:=L(BN(1));
foreach p2,e2 in (factor2PP(t)){
qs=[[(e,q); [0..e2]; qs; '{ q*BN(p2).pow(e) }]];
}
qs.filter1('wrap(q){ a.powm(q,m)==1 });
}
fcn multiOrder(a,m){
if (m.gcd(a)!=1) throw(Exception.ValueError("Not co-prime"));
res:=BN(1);
foreach p,e in (factor2PP(m)){
res = res.lcm(_multOrdr1(BN(a),BN(p),e));
}
return(res);
}

View file

@ -0,0 +1,9 @@
multiOrder(37,1000).println();
b:=BN(10).pow(20)-1;
multiOrder(2,b).println();
multiOrder(17,b).println();
b=0d10_0001;
[BN(1)..multiOrder(54,b)-1].filter1('wrap(r,b54){b54.powm(r,b)==1},BN(54)) :
if (_) println("Exists a power r < 9090 where (54^r)%b)==1");
else println("Everything checks.");