June 2018 Update
This commit is contained in:
parent
ba8067c3b7
commit
22f33d4004
5278 changed files with 84726 additions and 14379 deletions
|
|
@ -3,5 +3,5 @@ Lucas-Lehmer Test: for <math>p</math> an odd prime, the Mersenne number <math>2^
|
|||
|
||||
;Task:
|
||||
Calculate all Mersenne primes up to the implementation's
|
||||
maximum precision, or the 47th Mersenne prime (whichever comes first).
|
||||
maximum precision, or the 47<sup>th</sup> Mersenne prime (whichever comes first).
|
||||
<br><br>
|
||||
|
|
|
|||
8
Task/Lucas-Lehmer-test/Forth/lucas-lehmer-test.fth
Normal file
8
Task/Lucas-Lehmer-test/Forth/lucas-lehmer-test.fth
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
: lucas-lehmer
|
||||
1+ 2 do
|
||||
4 i 2 <> * abs swap 1+ dup + 1- swap
|
||||
i 1- 1 ?do dup * 2 - over mod loop 0= if ." M" i . then
|
||||
loop cr
|
||||
;
|
||||
|
||||
1 15 lucas-lehmer
|
||||
16
Task/Lucas-Lehmer-test/Julia/lucas-lehmer-test.julia
Normal file
16
Task/Lucas-Lehmer-test/Julia/lucas-lehmer-test.julia
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
using Primes
|
||||
|
||||
function getmersenneprimes(n)
|
||||
t1 = time()
|
||||
count = 0
|
||||
i = 2
|
||||
while(n > count)
|
||||
if(isprime(i) && ismersenneprime(2^BigInt(i) - 1))
|
||||
println("M$i, cumulative time elapsed: $(time() - t1) seconds")
|
||||
count += 1
|
||||
end
|
||||
i += 1
|
||||
end
|
||||
end
|
||||
|
||||
getmersenneprimes(50)
|
||||
33
Task/Lucas-Lehmer-test/R/lucas-lehmer-test.r
Normal file
33
Task/Lucas-Lehmer-test/R/lucas-lehmer-test.r
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
# vectorized approach based on scalar code from primeSieve and mersenne in CRAN package `numbers`
|
||||
require(gmp)
|
||||
n <- 4423 # note that the sieve below assumes n > 9
|
||||
|
||||
# sieve the set of primes up to n
|
||||
p <- seq(1, n, by = 2)
|
||||
q <- length(p)
|
||||
p[1] <- 2
|
||||
for (k in seq(3, sqrt(n), by = 2))
|
||||
if (p[(k + 1)/2] != 0)
|
||||
p[seq((k * k + 1)/2, q, by = k)] <- 0
|
||||
p <- p[p > 0]
|
||||
cat(p[1]," special case M2 == 3\n")
|
||||
p <- p[-1]
|
||||
|
||||
z2 <- gmp::as.bigz(2)
|
||||
z4 <- z2 * z2
|
||||
zp <- gmp::as.bigz(p)
|
||||
zmp <- z2^zp - 1
|
||||
S <- rep(z4, length(p))
|
||||
|
||||
for (i in 1:(p[length(p)] - 2)){
|
||||
S <- gmp::mod.bigz(S * S - z2, zmp)
|
||||
if( i+2 == p[1] ){
|
||||
if( S[1] == 0 ){
|
||||
cat( p[1], "\n")
|
||||
flush.console()
|
||||
}
|
||||
p <- p[-1]
|
||||
zmp <- zmp[-1]
|
||||
S <- S[-1]
|
||||
}
|
||||
}
|
||||
|
|
@ -1,58 +1,54 @@
|
|||
/*REXX program uses the Lucas─Lehmer primality test for prime powers of two.*/
|
||||
trace i
|
||||
parse arg limit . /*get optional arguments from the C.L. */
|
||||
if limit=='' then limit=1000 /*No argument? Then assume the default*/
|
||||
list= /*placeholder for the results. */
|
||||
/* [↓] only process up to the LIMIT, */
|
||||
do j=1 by 2 to limit /*there're only so many hours in a day.*/
|
||||
power=j + (j==1) /*POWER ≡ J except for when J=1. */
|
||||
if \isPrime(power) then iterate /*if POWER isn't prime, then ignore it.*/
|
||||
$=Lucas_Lehmer2(power) /*did it pass the Lucas─Lehmer2 test? */
|
||||
if $\=='' then list=list $ /*Did the # pass? Then add to the list.*/
|
||||
end /*j*/
|
||||
|
||||
list=space(list) /*elide all extraneous blanks from list*/
|
||||
say; say center('list',60-3,"═") /*show a fancy─dancy header (title). */
|
||||
say
|
||||
do k=1 for words(list) /*show entries in list, one per line. */
|
||||
say right(word(list,k),30) /*right─justify 'em to look pretty&nice*/
|
||||
end /*k*/
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────ISPRIME subroutine────────────────────────*/
|
||||
isPrime: procedure; parse arg x /*get number to be tested.*/
|
||||
if x<17 then return wordpos(x,'2 3 5 7 11 13')\==0 /*test for special cases. */
|
||||
if x//2==0 then return 0 /*is it even? Then not prime.*/
|
||||
if x//3==0 then return 0 /*divisible by three? " " " */
|
||||
if right(x,1)==5 then return 0 /*right-most dig ≡ 5? " " " */
|
||||
if x//7==0 then return 0 /*divisible by seven? " " " */
|
||||
|
||||
do j=11 by 6 until j*j>x /*ensures that J isn't divisible by 3. */
|
||||
if x// j ==0 then return 0 /*is it divisible by J ? */
|
||||
if x//(j+2)==0 then return 0 /* " " " " J+2 ? ___ */
|
||||
end /*j*/ /* [↑] perform loop through √ x */
|
||||
return 1 /*indicate the number X is prime. */
|
||||
/*──────────────────────────────────LUCAS_LEHMER2 subroutine──────────────────*/
|
||||
Lucas_Lehmer2: procedure; parse arg ? /*Lucas─Lehmer test on 2**? - 1 */
|
||||
numeric form /*ensure the correct REXX number form. */
|
||||
if ?==2 then s=0 /*handle special case for an even prime*/
|
||||
else s=4
|
||||
q=2**? /*╔═══════════════════════════════════════════════════════════════╗
|
||||
║ Compute a power of two, using only 9 decimal digits. DIGITs ║
|
||||
║ of 1 million could be used, but that really gums up the whole ║
|
||||
║ works. So, we start with the default of 9 digits, find the ║
|
||||
║ ten's exponent in the product (2**?), double it, and then add ║
|
||||
║ 6. 2 is all that's needed, but 6 is a lot safer. ║
|
||||
║ The doubling is for the squaring of S (below, for s*s). ║
|
||||
╚═══════════════════════════════════════════════════════════════╝*/
|
||||
if pos('E',q)\==0 then do /*the number in exponential notation? */
|
||||
parse var q 'E' tenpow
|
||||
numeric digits tenpow*2 + 6
|
||||
end
|
||||
else numeric digits digits()*2 + 6 /* 9*2 + 6 */
|
||||
q=2**?-1
|
||||
do ?-2 /*apply, rinse, repeat ··· */
|
||||
s=(s*s-2) // q /*remainder in REXX is: // */
|
||||
end /* [↑] compute the real McCoy. */
|
||||
|
||||
if s\==0 then return '' /*return nuttin' if number isn't prime.*/
|
||||
return 'M'? /*return a "modified" (prime) number. */
|
||||
/*REXX pgm uses the Lucas─Lehmer primality test for prime powers of 2 (Mersenne primes)*/
|
||||
@.=0; @.2=1; @.3=1; @.5=1; @.7=1; @.11=1; @.13=1 /*a partial list of some low primes. */
|
||||
!.=@.; !.0=1; !.2=1; !.4=1; !.5=1; !.6=1; !.8=1 /*#'s with these last digs aren't prime*/
|
||||
parse arg limit . /*obtain optional arguments from the CL*/
|
||||
if limit=='' then limit= 200 /*Not specified? Then use the default.*/
|
||||
say center('Mersenne prime index list',70-3,"═") /*show a fancy─dancy header (or title).*/
|
||||
say right('M'2, 25) " [1 decimal digit]" /*left─justify them to align&look nice.*/
|
||||
/* [►] note that J==1 is a special case*/
|
||||
do j=1 by 2 to limit /*there're only so many hours in a day.*/
|
||||
power=j + (j==1) /*POWER ≡ J except for when J=1. */
|
||||
if \isPrime(power) then iterate /*if POWER isn't prime, then ignore it.*/
|
||||
$=LL2(power) /*perform the Lucas─Lehmer 2 (LL2) test*/
|
||||
if $=='' then iterate /*Did it flunk LL2? Then skip this #.*/
|
||||
say right($, 25) MPsize /*left─justify them to align&look nice.*/
|
||||
end /*j*/
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
isPrime: procedure expose !. @.; parse arg x '' -1 z /*get # to be tested & last digit*/
|
||||
if @.x then return 1 /*is X already found to be prime? */
|
||||
if !.z then return 0 /*is last decimal digit even or a five?*/
|
||||
if x//3==0 then return 0 /*divisible by three? " " " */
|
||||
if x//7==0 then return 0 /*divisible by seven? " " " */
|
||||
do j=11 by 6 until j*j > x /*ensures that J isn't divisible by 3. */
|
||||
if x// j ==0 then return 0 /*is it divisible by J ? */
|
||||
if x// (j+2)==0 then return 0 /* " " " " J+2 ? ___ */
|
||||
end /*j*/ /* [↑] perform loop through √ x */
|
||||
@.j=1; return 1 /*indicate number X and J are prime.*/
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
LL2: procedure expose MPsize; parse arg ? /*Lucas─Lehmer test on 2**? - 1 */
|
||||
if ?==2 then s=0 /*handle special case for an even prime*/
|
||||
else s=4
|
||||
numeric form; q= 2**? /*ensure correct form for REXX numbers.*/
|
||||
/*╔══════════════════════════════════════════════════════════════════════════════════╗
|
||||
║ Compute a power of two, using only 9 decimal digits. DIGITs of 1 million could ║
|
||||
║ be used, but that really slows up computations. So, we start with the default ║
|
||||
║ of 9 digits, and then find the ten's exponent in the product (2**?), double ║
|
||||
║ it, and then add six. {Two is all that's needed, but six is a lot safer.} ║
|
||||
║ The doubling is for the squaring of S (below, for s*s). ║
|
||||
╚══════════════════════════════════════════════════════════════════════════════════╝*/
|
||||
if pos('E', q)\==0 then do /*is number in exponential notation ? */
|
||||
parse var q 'E' tenPow /*get the exponent.*/
|
||||
numeric digits tenPow * 2 + 6 /*expand precision.*/
|
||||
end /*REXX used dec FP.*/
|
||||
else numeric digits digits() * 2 + 6 /*use 9*2 + 6 digs.*/
|
||||
q=2**? - 1; r=q//8 /*obtain Q modulus eight. */
|
||||
if r==1 | r==7 then nop; else return '' /*before crunching, do a simple test. */
|
||||
do ?-2; s= (s*s -2) // q /*lather, rinse, repeat ··· */
|
||||
end /* [↑] compute and test for a MP. */
|
||||
if s\==0 then return '' /*Not a Mersenne prime? Return a null.*/
|
||||
sz=length(q) /*obtain number of decimal digs in MP. */
|
||||
MPsize=' ['sz "decimal digit"s(sz)']' /*define a literal to display after MP.*/
|
||||
return 'M'? /*return "modified" # (Mersenne index).*/
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
s: if arg(1)==1 then return arg(3); return word(arg(2) 's', 1) /*simple pluralizer*/
|
||||
|
|
|
|||
53
Task/Lucas-Lehmer-test/Rust/lucas-lehmer-test.rust
Normal file
53
Task/Lucas-Lehmer-test/Rust/lucas-lehmer-test.rust
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
extern crate rug;
|
||||
extern crate primal;
|
||||
|
||||
use rug::Integer;
|
||||
use rug::ops::Pow;
|
||||
use std::thread::spawn;
|
||||
|
||||
fn is_mersenne (p : usize) {
|
||||
let p = p as u32;
|
||||
let mut m = Integer::from(1);
|
||||
m = m << p;
|
||||
m = Integer::from(&m - 1);
|
||||
let mut flag1 = false;
|
||||
for k in 1..10_000 {
|
||||
let mut flag2 = false;
|
||||
let mut div : u32 = 2*k*p + 1;
|
||||
if &div >= &m {break; }
|
||||
for j in [3,5,7,11,13,17,19,23,29,31,37].iter() {
|
||||
if div % j == 0 {
|
||||
flag2 = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if flag2 == true {continue;}
|
||||
if div % 8 != 1 && div % 8 != 7 { continue; }
|
||||
if m.is_divisible_u(div) {
|
||||
flag1 = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if flag1 == true {return ()}
|
||||
let mut s = Integer::from(4);
|
||||
let two = Integer::from(2);
|
||||
for _i in 2..p {
|
||||
let mut sqr = s.pow(2);
|
||||
s = Integer::from(&Integer::from(&sqr & &m) + &Integer::from(&sqr >> p));
|
||||
if &s >= &m {s = s - &m}
|
||||
s = Integer::from(&s - &two);
|
||||
}
|
||||
if s == 0 {println!("Mersenne : {}",p);}
|
||||
}
|
||||
|
||||
fn main () {
|
||||
println!("Mersenne : 2");
|
||||
let limit = 11_214;
|
||||
let mut thread_handles = vec![];
|
||||
for p in primal::Primes::all().take_while(|p| *p < limit) {
|
||||
thread_handles.push(spawn(move || is_mersenne(p)));
|
||||
}
|
||||
for handle in thread_handles {
|
||||
handle.join().unwrap();
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue