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

@ -20,6 +20,7 @@ Show output on this page.
'''Note 2:''' If a languages in-built prime generator is extensible or is guaranteed to generate primes up to a system limit, (2<sup>31</sup> or memory overflow for example), then this may be used as long as an explanation of the limits of the prime generator is also given. (Which may include a link to/excerpt from, language documentation).
;See also:
* The task is written so it may be useful in solving task [[Emirp primes]] as well as others (depending on its efficiency).
;Related task:
* The task is written so it may be useful in solving the task &nbsp; [[Emirp primes]] &nbsp; as well as others (depending on its efficiency).
<br><br>

View file

@ -303,8 +303,24 @@ Can invoke GETSREC, which can invoke PSURGE, which ... invokes NEXTPRIME. Oh dea
LOGICAL FUNCTION ISPRIME(N) !Could fool around explicity testing 2 and 3 and say 5,
INTEGER N !But that means also checking that N > 2, N > 3, and N > 5.
ISPRIME = N .EQ. NEXTPRIME(N - 1) !This is so much easier.
END FUNCTION ISPRIME !No divisions up to SQRT(N) or the like either.
c ISPRIME = N .EQ. NEXTPRIME(N - 1) !This is so much easier, but involves scanning to reach the next prime.
INTEGER R,IST,I,C,B !Assistants for indexing the bit array.
IF (N.LE.1) THEN !First, preclude sillyness.
ISPRIME = .FALSE. !Not a prime.
ELSE IF (N.EQ.2) THEN !This is the only even number
ISPRIME = .TRUE. !That is a prime.
ELSE IF (MOD(N,2).EQ.0) THEN !Other even numbers
ISPRIME = .FALSE. !Are not prime numbers.
ELSE !Righto, now N is an odd number and there is a bit array for them.
R = (N - SORG)/(2*SBITS) !SORG is odd, so (N - SORG) is even.
CALL GETSREC(R + 1) !The first record is numbered one, not zero.
IST = SORG + R*(2*SBITS) !The number for its first bit: even numbers are omitted.
I = (N - IST)/2 !Offset into the record. N - IST is even.
C = I/8 !Which character in SCHAR(0:SCHARS - 1)?
B = MOD(I,8) !Which bit in SCHAR(C), indexing from zero?
ISPRIME = IAND(ICHAR(SCHAR(C)),ICHAR(BITON(B))).GT.0 !The bit is on for a prime.
END IF !All that fuss to find a single bit.
END FUNCTION ISPRIME !But, no divisions up to SQRT(N) or the like.
END MODULE PRIMEBAG !Functions updating a disc file as a side effect...
PROGRAM POKE

View file

@ -0,0 +1,36 @@
// version 1.1.2
// compiled with flag -Xcoroutines=enable to suppress 'experimental' warning
import kotlin.coroutines.experimental.*
fun isPrime(n: Int) : Boolean {
if (n < 2) return false
if (n % 2 == 0) return n == 2
if (n % 3 == 0) return n == 3
var d : Int = 5
while (d * d <= n) {
if (n % d == 0) return false
d += 2
if (n % d == 0) return false
d += 4
}
return true
}
fun generatePrimes() =
buildSequence {
yield(2)
var p = 3
while (p <= Int.MAX_VALUE) {
if (isPrime(p)) yield(p)
p += 2
}
}
fun main(args: Array<String>) {
val primes = generatePrimes().take(10000) // generate first 10,000 primes
println("First 20 primes : ${primes.take(20).toList()}")
println("Primes between 100 and 150 : ${primes.filter { it in 100..150 }.toList()}")
println("Number of primes between 7700 and 8000 = ${primes.filter { it in 7700..8000 }.count()}")
println("10,000th prime = ${primes.last()}")
}

View file

@ -0,0 +1,59 @@
sequence primes = {2,3,5,7}
atom sieved = 10
procedure add_block()
integer N = min((sieved-1)*sieved,400000)
sequence sieve = repeat(1,N) -- sieve[i] is really i+sieved
for i=2 to length(primes) do -- (evens filtered on output)
atom p = primes[i], p2 = p*p
if p2>sieved+N then exit end if
if p2<sieved+1 then
p2 += ceil((sieved+1-p2)/p)*p
end if
p2 -= sieved
if and_bits(p2,1)=0 then p2 += p end if
-- if sieve[p2] then -- dang!
for k=p2 to N by p*2 do
sieve[k] = 0
end for
-- end if
end for
for i=1 to N by 2 do
if sieve[i] then
primes &= i+sieved
end if
end for
sieved += N
end procedure
function is_prime(integer n)
while sieved<n do
add_block()
end while
return binary_search(n,primes)>0
end function
atom t0 = time()
while length(primes)<20 do add_block() end while
printf(1,"The first 20 primes are: ") ?primes[1..20]
while sieved<150 do add_block() end while
sequence s = {}
for k=abs(binary_search(100,primes)) to length(primes) do
integer p = primes[k]
if p>150 then exit end if
s &= p
end for
printf(1,"The primes between 100 and 150 are: ") ?s
s = {}
for i=7700 to 8000 do
if is_prime(i) then s&=i end if
end for
printf(1,"There are %d primes between 7700 and 8000.\n",length(s))
for i=1 to 8 do
integer k = power(10,i)
while length(primes)<k do
add_block()
end while
printf(1,"The %dth prime is : %d\n",{k,primes[k]})
end for
?time()-t0

View file

@ -0,0 +1,54 @@
EnableExplicit
DisableDebugger
Define StartTime.i=ElapsedMilliseconds()
Procedure.b IsPrime(n.i)
Define i.i=5
If n<2 : ProcedureReturn #False : EndIf
If n%2=0 : ProcedureReturn Bool(n=2) : EndIf
If n%3=0 : ProcedureReturn Bool(n=3) : EndIf
While i*i<=n
If n%i=0 : ProcedureReturn #False : EndIf
i+2
If n%i=0 : ProcedureReturn #False : EndIf
i+4
Wend
ProcedureReturn #True
EndProcedure
If OpenConsole("Extensible prime generator")
Define c.i=0, n.i=2
Print("First twenty: ")
While c<20
If IsPrime(n)
Print(Str(n)+" ")
c+1
EndIf
n+1
Wend
Print(~"\nBetween 100 and 150: ")
For n=100 To 150
If IsPrime(n)
Print(Str(n)+" ")
EndIf
Next
Print(~"\nNumber beween 7'700 and 8'000: ")
c=0
For n=7700 To 8000
c+IsPrime(n)
Next
Print(Str(c))
Print(~"\n10'000th prime: ")
c=0 : n=1
While c<10000
n+1
c+IsPrime(n)
Wend
Print(Str(n))
EndIf
Print(~"\nRuntime milliseconds: "+
Str(ElapsedMilliseconds()-StartTime))
Input()

View file

@ -1,46 +1,46 @@
/*REXX program calculates and displays primes using an extendible prime number generator*/
parse arg f .; if f=='' then f=20 /*allow specifying number for 1 ──► F.*/
call primes f; do j=1 for f; $=$ @.j; end /*j*/
say 'first' f 'primes are:' $
say
call primes f; do j=1 for f; $=$ @.j; end /*j*/
say 'first' f 'primes are:' $
say
call primes -150; do j=100 to 150; if !.j==0 then iterate; $=$ j; end /*j*/
say 'the primes between 100 to 150 (inclusive) are:' $
say
say 'the primes between 100 to 150 (inclusive) are:' $
say
call primes -8000; do j=7700 to 8000; if !.j==0 then iterate; $=$ j; end /*j*/
say 'the number of primes between 7700 and 8000 (inclusive) is:' words($)
say
say 'the number of primes between 7700 and 8000 (inclusive) is:' words($)
say
call primes 10000
say 'the 10000th prime is:' @.10000
say 'the 10000th prime is:' @.10000
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
primes: procedure expose !. s. @. $ #; parse arg H . 1 m .,,$; H=abs(H)
if symbol('!.0')=='LIT' then /*1st time here? Then initialize stuff*/
do; !.=0; @.=0; s.=0 /*!.x = some prime; @.n = Nth prime. */
_=2 3 5 7 11 13 17 19 23 /*generate a bunch of low primes. */
do #=1 for words(_); p=word(_,#); @.#=p; !.p=1; end
#=#-1; !.0=#; s.#=@.#**2 /*set # to be the number of primes. */
end /* [↑] done with building low primes? */
neg= m<0 /*Negative? Request is for a P value.*/
if neg then if H<=@.# then return /*do we have a high enough P already?*/
else nop /*this is used to match the above THEN.*/
else if H<=# then return /*do we have a enough primes already ? */
primes: procedure expose !. s. @. $ #; parse arg H,,$; Hneg=H<0; H=abs(H)
if symbol('!.0')=="LIT" then do /*1st time here? Then initialize stuff*/
!.=0; @.=0; s.=0 /*!.x=a prime; @.n=Nth prime.*/
L=2 3 5 7 11 13 17 19 23 /*gen some low primes.*/
do #=1 for words(L); p=word(L, #); @.#=p; !.p=1
end /*#*/
#=#-1; !.0=#; s.#=@.#**2 /*set #≡numb. of primes*/
end
if Hneg then if H<=@.# then return /*do we have a high enough P already?*/
else nop /*this is used to match the above THEN.*/
else if H<=# then return /*are there enough primes currently ? */
/* [↓] gen more primes within range. */
do j=@.#+2 by 2 /*find primes until have H Primes. */
if j//3 ==0 then iterate /*is J divisible by three? */
parse var j '' -1 _; if _==5 then iterate /*is the right-most digit a 5?*/
if j//7 ==0 then iterate /*is J divisible by seven? */
if j//11==0 then iterate /*is J divisible by eleven? */
if j//13==0 then iterate /*is J divisible by thirteen? */
if j//17==0 then iterate /*is J divisible by seventeen? */
if j//19==0 then iterate /*is J divisible by nineteen? */
/*[↑] above five lines saves time. */
do k=!.0 while s.k<=j /*divide by the known odd primes. */
if j//@.k==0 then iterate j /*Is J ÷ by a prime? ¬prime. ___*/
end /*k*/ /* [↑] divide by odd primes up to √ j */
#=#+1 /*bump the number of primes found. */
@.#=j; s.#=j*j; !.j=1 /*assign to sparse array; prime²; P#.*/
if neg then if H<=@.# then leave /*do we have a high enough prime? */
do j=@.# + 2 by 2 /*find primes until have H Primes. */
if j//3 ==0 then iterate /*is J divisible by three? */
parse var j '' -1 _; if _==5 then iterate /*is the right─most digit a 5?*/
if j//7 ==0 then iterate /*is J divisible by seven? */
if j//11==0 then iterate /* " " " " eleven? */
if j//13==0 then iterate /* " " " " thirteen? */
if j//17==0 then iterate /* " " " " seventeen? */
if j//19==0 then iterate /* " " " " nineteen? */
/*[↑] above divisors go up to L end.*/
do k=!.0 while s.k<=j /*divide by the known odd primes. */
if j//@.k==0 then iterate j /*Is J ÷ by a prime? ¬prime. ___*/
end /*k*/ /* [↑] divide by odd primes up to √ J */
#=#+1 /*bump the number of primes found. */
@.#=j; s.#=j * j; !.j=1 /*assign to sparse array; prime²; P#.*/
if Hneg then if H<=@.# then leave /*is this a high enough prime? */
else nop /*used to match the above THEN. */
else if H<=# then leave /*do we have enough primes yet? */
end /*j*/ /* [↑] keep generating until enough. */
else if H<=# then leave /*have enough primes been generated? */
end /*j*/ /* [↑] keep generating until enough. */
return /*return to invoker with more primes. */

View file

@ -0,0 +1,15 @@
mod pagesieve;
use pagesieve::{count_primes_paged, primes_paged};
fn main() {
println!("First 20 primes:\n {:?}",
primes_paged().take(20).collect::<Vec<_>>());
println!("Primes between 100 and 150:\n {:?}",
primes_paged().skip_while(|&x| x < 100)
.take_while(|&x| x < 150)
.collect::<Vec<_>>());
let diff = count_primes_paged(8000) - count_primes_paged(7700);
println!("There are {} primes between 7,700 and 8,000", diff);
println!("The 10,000th prime is {}", primes_paged().nth(10_000).unwrap());
}

View file

@ -0,0 +1,30 @@
// http://stackoverflow.com/revisions/10733621/4
fcn postponed_sieve(){ # postponed sieve, by Will Ness
vm.yield(2); vm.yield(3); # original code David Eppstein,
vm.yield(5); vm.yield(7); # ActiveState Recipe 2002
D:=Dictionary();
ps:=Utils.Generator(postponed_sieve); # a separate Primes Supply:
p:=ps.pump(2,Void); # (3) a Prime to add to dict
q:=p*p; # (9) when its sQuare is
c:=9; # the next Candidate
while(1){
if (not D.holds(c)){ # not a multiple of any prime seen so far:
if (c < q) vm.yield(c); # a prime, or
else{ # (c==q): # the next prime's square:
add(D,c + 2*p,2*p); # (9+6,6 : 15,21,27,33,...)
p=ps.next(); # (5)
q=p*p; # (25)
}
}else{ # 'c' is a composite:
s := D.pop(c); # step of increment
add(D,c + s,s); # next multiple, same step
}
c += 2; # next odd candidate
}
}
fcn add(D,x,s){ # make no multiple keys in Dict
while(D.holds(x)){ x += s } # increment by the given step
D[x] = s;
}

View file

@ -0,0 +1,16 @@
primes:=Utils.Generator(postponed_sieve);
primes.walk(20).println(); // first 20 primes
primes.pump(List,fcn(p){ // the primes between 100 & 150
if (p<100) Void.Skip else if(p>150) Void.Stop else p
}).println();
primes.reduce(fcn(n,p){ // count of primes between 7700 & 8000
if (p<=7700) n else if(p>8000) Void.Stop else n+1
},0).println();
primes=Utils.Generator(postponed_sieve); // new Generator
primes.drop(0d9_999); primes.next().println(); // 10,000th prime
// or to carry on until the 100,000th:
primes.pump(Void,'wrap(p){ primes.n<=0d100_000 and p or Void.Stop }).println();

View file

@ -0,0 +1,2 @@
var [const] BN=Import("zklBigNum"); // libGMP
bigPrimes:=Walker(fcn(p){ p.nextPrime().copy(); }.fp(BN(1)));

View file

@ -0,0 +1,2 @@
bigPrimes.walk(20).println(); // first 20 primes
bigPrimes.pump(Void,'wrap(p){ bigPrimes.n<=0d10_000 and p or Void.Stop }).println();