Update all new Tasks
This commit is contained in:
parent
00a190b0a6
commit
91df62d461
5697 changed files with 93386 additions and 804 deletions
21
Task/Extensible-prime-generator/00DESCRIPTION
Normal file
21
Task/Extensible-prime-generator/00DESCRIPTION
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
The task is to write a generator of prime numbers, in order, that will automatically adjust to accommodate the generation of any reasonably high prime.
|
||||
|
||||
The routine should demonstrably rely on either:
|
||||
# Being based on an open-ended counter set to count without upper limit other than system or programming language limits. In this case, explain where this counter is in the code.
|
||||
# Being based on a limit that is extended automatically. In this case, choose a small limit that ensures the limit will be passed when generating some of the values to be asked for below.
|
||||
# If other methods of creating an extensible prime generator are used, the algorithm's means of extensibility/lack of limits should be stated.
|
||||
|
||||
The routine should be used to:
|
||||
* Show the first twenty primes.
|
||||
* Show the primes between 100 and 150.
|
||||
* Show the ''number'' of primes between 7,700 and 8,000.
|
||||
* Show the 10,000th prime.
|
||||
|
||||
Show output on this page.
|
||||
|
||||
'''Note:''' You may reference code already on this site if it is written to be imported/included, then only the code necessary for import and the performance of this task need be shown. (It is also important to leave a forward link on the referenced tasks entry so that later editors know that the code is used for multiple tasks).
|
||||
|
||||
'''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).
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
with Ada.Text_IO, Miller_Rabin;
|
||||
|
||||
procedure Prime_Gen is
|
||||
|
||||
type Num is range 0 .. 2**63-1; -- maximum for the gnat Ada compiler
|
||||
|
||||
MR_Iterations: constant Positive := 25;
|
||||
-- the probability Pr[Is_Prime(N, MR_Iterations) = Probably_Prime]
|
||||
-- is 1 for prime N and < 4**(-MR_Iterations) for composed N
|
||||
|
||||
function Next(P: Num) return Num is
|
||||
N: Num := P+1;
|
||||
package MR is new Miller_Rabin(Num); use MR;
|
||||
begin
|
||||
while not (Is_Prime(N, MR_Iterations) = Probably_Prime) loop
|
||||
N := N + 1;
|
||||
end loop;
|
||||
return N;
|
||||
end Next;
|
||||
|
||||
Current: Num;
|
||||
Count: Num := 0;
|
||||
|
||||
begin
|
||||
-- show the first twenty primes
|
||||
Ada.Text_IO.Put("First 20 primes:");
|
||||
Current := 1;
|
||||
for I in 1 .. 20 loop
|
||||
Current := Next(Current);
|
||||
Ada.Text_IO.Put(Num'Image(Current));
|
||||
end loop;
|
||||
Ada.Text_IO.New_Line;
|
||||
|
||||
-- show the primes between 100 and 150
|
||||
Ada.Text_IO.Put("Primes between 100 and 150:");
|
||||
Current := 99;
|
||||
loop
|
||||
Current := Next(Current);
|
||||
exit when Current > 150;
|
||||
Ada.Text_IO.Put(Num'Image(Current));
|
||||
end loop;
|
||||
Ada.Text_IO.New_Line;
|
||||
|
||||
-- count primes between 7700 and 8000
|
||||
Ada.Text_IO.Put("Number of primes between 7700 and 8000:");
|
||||
Current := 7699;
|
||||
loop
|
||||
Current := Next(Current);
|
||||
exit when Current > 8000;
|
||||
Count := Count + 1;
|
||||
end loop;
|
||||
Ada.Text_IO.Put_Line(Num'Image(Count));
|
||||
|
||||
Count := 10;
|
||||
Ada.Text_IO.Put_Line("Print the K_i'th prime, for $K=10**i:");
|
||||
begin
|
||||
loop
|
||||
Current := 1;
|
||||
for I in 1 .. Count loop
|
||||
Current := Next(Current);
|
||||
end loop;
|
||||
Ada.Text_IO.Put(Num'Image(Count) & "th prime:" &
|
||||
Num'Image(Current));
|
||||
Count := Count * 10;
|
||||
end loop;
|
||||
exception
|
||||
when Constraint_Error =>
|
||||
Ada.Text_IO.Put_Line(" can't compute the" & Num'Image(Count) &
|
||||
"th prime:");
|
||||
end;
|
||||
end;
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
SetBatchLines, -1
|
||||
p := 1 ;p functions as the counter
|
||||
Loop, 10000 {
|
||||
p := NextPrime(p)
|
||||
if (A_Index < 21)
|
||||
a .= p ", "
|
||||
if (p < 151 && p > 99)
|
||||
b .= p ", "
|
||||
if (p < 8001 && p > 7699)
|
||||
c++
|
||||
}
|
||||
MsgBox, % "First twenty primes: " RTrim(a, ", ")
|
||||
. "`nPrimes between 100 and 150: " RTrim(b, ", ")
|
||||
. "`nNumber of primes between 7,700 and 8,000: " RTrim(c, ", ")
|
||||
. "`nThe 10,000th prime: " p
|
||||
|
||||
NextPrime(n) {
|
||||
Loop
|
||||
if (IsPrime(++n))
|
||||
return n
|
||||
}
|
||||
|
||||
IsPrime(n) {
|
||||
if (n < 2)
|
||||
return, 0
|
||||
else if (n < 4)
|
||||
return, 1
|
||||
else if (!Mod(n, 2))
|
||||
return, 0
|
||||
else if (n < 9)
|
||||
return 1
|
||||
else if (!Mod(n, 3))
|
||||
return, 0
|
||||
else {
|
||||
r := Floor(Sqrt(n))
|
||||
f := 5
|
||||
while (f <= r) {
|
||||
if (!Mod(n, f))
|
||||
return, 0
|
||||
if (!Mod(n, (f + 2)))
|
||||
return, 0
|
||||
f += 6
|
||||
}
|
||||
return, 1
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#define CHUNK_BYTES (32 << 8)
|
||||
#define CHUNK_SIZE (CHUNK_BYTES << 6)
|
||||
|
||||
int field[CHUNK_BYTES];
|
||||
#define GET(x) (field[(x)>>6] & 1<<((x)>>1&31))
|
||||
#define SET(x) (field[(x)>>6] |= 1<<((x)>>1&31))
|
||||
|
||||
typedef unsigned uint;
|
||||
typedef struct {
|
||||
uint *e;
|
||||
uint cap, len;
|
||||
} uarray;
|
||||
uarray primes, offset;
|
||||
|
||||
void push(uarray *a, uint n)
|
||||
{
|
||||
if (a->len >= a->cap) {
|
||||
if (!(a->cap *= 2)) a->cap = 16;
|
||||
a->e = realloc(a->e, sizeof(uint) * a->cap);
|
||||
}
|
||||
a->e[a->len++] = n;
|
||||
}
|
||||
|
||||
uint low;
|
||||
void init(void)
|
||||
{
|
||||
uint p, q;
|
||||
|
||||
unsigned char f[1<<16];
|
||||
memset(f, 0, sizeof(f));
|
||||
push(&primes, 2);
|
||||
push(&offset, 0);
|
||||
for (p = 3; p < 1<<16; p += 2) {
|
||||
if (f[p]) continue;
|
||||
for (q = p*p; q < 1<<16; q += 2*p) f[q] = 1;
|
||||
push(&primes, p);
|
||||
push(&offset, q);
|
||||
}
|
||||
low = 1<<16;
|
||||
}
|
||||
|
||||
void sieve(void)
|
||||
{
|
||||
uint i, p, q, hi, ptop;
|
||||
if (!low) init();
|
||||
|
||||
memset(field, 0, sizeof(field));
|
||||
|
||||
hi = low + CHUNK_SIZE;
|
||||
ptop = sqrt(hi) * 2 + 1;
|
||||
|
||||
for (i = 1; (p = primes.e[i]*2) < ptop; i++) {
|
||||
for (q = offset.e[i] - low; q < CHUNK_SIZE; q += p)
|
||||
SET(q);
|
||||
offset.e[i] = q + low;
|
||||
}
|
||||
|
||||
for (p = 1; p < CHUNK_SIZE; p += 2)
|
||||
if (!GET(p)) push(&primes, low + p);
|
||||
|
||||
low = hi;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
uint i, p, c;
|
||||
|
||||
while (primes.len < 20) sieve();
|
||||
printf("First 20:");
|
||||
for (i = 0; i < 20; i++)
|
||||
printf(" %u", primes.e[i]);
|
||||
putchar('\n');
|
||||
|
||||
while (primes.e[primes.len-1] < 150) sieve();
|
||||
printf("Between 100 and 150:");
|
||||
for (i = 0; i < primes.len; i++) {
|
||||
if ((p = primes.e[i]) >= 100 && p < 150)
|
||||
printf(" %u", primes.e[i]);
|
||||
}
|
||||
putchar('\n');
|
||||
|
||||
while (primes.e[primes.len-1] < 8000) sieve();
|
||||
for (i = c = 0; i < primes.len; i++)
|
||||
if ((p = primes.e[i]) >= 7700 && p < 8000) c++;
|
||||
printf("%u primes between 7700 and 8000\n", c);
|
||||
|
||||
for (c = 10; c <= 100000000; c *= 10) {
|
||||
while (primes.len < c) sieve();
|
||||
printf("%uth prime: %u\n", c, primes.e[c-1]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
void main() {
|
||||
import std.stdio, std.range, std.algorithm, sieve_of_eratosthenes3;
|
||||
|
||||
Prime prime;
|
||||
writeln("First twenty primes:\n", 20.iota.map!prime);
|
||||
writeln("Primes primes between 100 and 150:\n",
|
||||
uint.max.iota.map!prime.until!q{a > 150}.filter!q{a > 99});
|
||||
writeln("Number of primes between 7,700 and 8,000: ",
|
||||
uint.max.iota.map!prime.until!q{a > 8_000}
|
||||
.filter!q{a > 7_699}.walkLength);
|
||||
writeln("10,000th prime: ", prime(9_999));
|
||||
}
|
||||
111
Task/Extensible-prime-generator/D/extensible-prime-generator-2.d
Normal file
111
Task/Extensible-prime-generator/D/extensible-prime-generator-2.d
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
/// Prime sieve based on: http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf
|
||||
|
||||
import std.container: Array, BinaryHeap, RedBlackTree;
|
||||
|
||||
struct LazyPrimeSieve {
|
||||
@property bool empty() const pure nothrow @safe @nogc {
|
||||
return i > 203_280_221; // Pi(2 ^^ 32).
|
||||
}
|
||||
|
||||
@property auto front() const pure nothrow @safe @nogc {
|
||||
return prime;
|
||||
}
|
||||
|
||||
@property void popFront() pure nothrow /*@safe*/ {
|
||||
prime = sieveOne();
|
||||
}
|
||||
|
||||
private:
|
||||
static struct Wheel2357 {
|
||||
static immutable ubyte[48] holes = [2, 4, 2, 4, 6, 2, 6, 4, 2, 4, 6, 6,
|
||||
2, 6, 4, 2, 6, 4, 6, 8, 4, 2, 4, 2, 4, 8, 6, 4, 6, 2, 4, 6, 2, 6, 6,
|
||||
4, 2, 4, 6, 2, 6, 4, 2, 4, 2, 10, 2, 10];
|
||||
static immutable ubyte[4] spokes = [2, 3, 5, 7];
|
||||
static immutable ubyte first = 11;
|
||||
uint i;
|
||||
|
||||
auto spin() pure nothrow @safe @nogc {
|
||||
return holes[i++ % $];
|
||||
}
|
||||
}
|
||||
|
||||
static struct CompositeIterator {
|
||||
uint prime;
|
||||
Wheel2357 wheel;
|
||||
ulong composite;
|
||||
|
||||
this(uint p) pure nothrow @safe @nogc {
|
||||
prime = p;
|
||||
composite = p * wheel.first;
|
||||
}
|
||||
|
||||
void next() pure nothrow @safe @nogc {
|
||||
composite += prime * wheel.spin;
|
||||
}
|
||||
}
|
||||
|
||||
version (heap) // Less memory but slower.
|
||||
BinaryHeap!(Array!CompositeIterator, "a.composite > b.composite") iterators;
|
||||
else // Faster but is more GC intensive.
|
||||
RedBlackTree!(CompositeIterator, "a.composite < b.composite", true) iterators;
|
||||
|
||||
uint prime = 2;
|
||||
uint i = 1;
|
||||
Wheel2357 wheel;
|
||||
uint candidate = wheel.first;
|
||||
|
||||
uint sieveOne() pure nothrow /*@safe*/ {
|
||||
switch (i) {
|
||||
case 0: .. case wheel.spokes.length - 1:
|
||||
return wheel.spokes[i++];
|
||||
|
||||
case wheel.spokes.length:
|
||||
i++;
|
||||
return candidate;
|
||||
|
||||
case wheel.spokes.length + 1:
|
||||
version (heap) {}
|
||||
else
|
||||
iterators = new typeof(iterators);
|
||||
goto default;
|
||||
|
||||
default:
|
||||
goto POST_RETURN;
|
||||
|
||||
while (true) {
|
||||
candidate += wheel.spin;
|
||||
|
||||
while (iterators.front.composite < candidate) {
|
||||
auto it = iterators.front;
|
||||
iterators.removeFront;
|
||||
it.next;
|
||||
iterators.insert(it);
|
||||
}
|
||||
|
||||
if (iterators.front.composite != candidate) {
|
||||
i++;
|
||||
return candidate;
|
||||
POST_RETURN:
|
||||
// Only insert primes that are multiply
|
||||
// occuring in [0, 2 ^^ 32).
|
||||
if (candidate < 2 ^^ 16)
|
||||
iterators.insert(CompositeIterator(candidate));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void main() /*@safe*/ {
|
||||
import std.stdio, std.algorithm, std.range;
|
||||
|
||||
writeln("Sum of first 100,000 primes: ", LazyPrimeSieve().take(100_000).sum(0uL));
|
||||
|
||||
writeln("First twenty primes:\n", LazyPrimeSieve().take(20));
|
||||
writeln("Primes primes between 100 and 150:\n",
|
||||
LazyPrimeSieve().until!q{a > 150}.filter!q{a > 99});
|
||||
writeln("Number of primes between 7,700 and 8,000: ",
|
||||
LazyPrimeSieve().until!q{a > 8_000}.filter!q{a > 7_699}.walkLength);
|
||||
writeln("10,000th prime: ", LazyPrimeSieve().dropExactly(9999).front);
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"container/heap"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func main() {
|
||||
p := newP()
|
||||
fmt.Print("First twenty: ")
|
||||
for i := 0; i < 20; i++ {
|
||||
fmt.Print(p(), " ")
|
||||
}
|
||||
fmt.Print("\nBetween 100 and 150: ")
|
||||
n := p()
|
||||
for n <= 100 {
|
||||
n = p()
|
||||
}
|
||||
for ; n < 150; n = p() {
|
||||
fmt.Print(n, " ")
|
||||
}
|
||||
for n <= 7700 {
|
||||
n = p()
|
||||
}
|
||||
c := 0
|
||||
for ; n < 8000; n = p() {
|
||||
c++
|
||||
}
|
||||
fmt.Println("\nNumber beween 7,700 and 8,000:", c)
|
||||
p = newP()
|
||||
for i := 1; i < 10000; i++ {
|
||||
p()
|
||||
}
|
||||
fmt.Println("10,000th prime:", p())
|
||||
}
|
||||
|
||||
func newP() func() int {
|
||||
n := 1
|
||||
var pq pQueue
|
||||
top := &pMult{2, 4, 0}
|
||||
return func() int {
|
||||
for {
|
||||
n++
|
||||
if n < top.pMult { // n is a new prime
|
||||
heap.Push(&pq, &pMult{prime: n, pMult: n * n})
|
||||
top = pq[0]
|
||||
return n
|
||||
}
|
||||
// n was next on the queue, it's a composite
|
||||
for top.pMult == n {
|
||||
top.pMult += top.prime
|
||||
heap.Fix(&pq, 0)
|
||||
top = pq[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type pMult struct {
|
||||
prime int
|
||||
pMult int
|
||||
index int
|
||||
}
|
||||
|
||||
type pQueue []*pMult
|
||||
|
||||
func (q pQueue) Len() int { return len(q) }
|
||||
func (q pQueue) Less(i, j int) bool { return q[i].pMult < q[j].pMult }
|
||||
func (q pQueue) Swap(i, j int) {
|
||||
q[i], q[j] = q[j], q[i]
|
||||
q[i].index = i
|
||||
q[j].index = j
|
||||
}
|
||||
func (p *pQueue) Push(x interface{}) {
|
||||
q := *p
|
||||
e := x.(*pMult)
|
||||
e.index = len(q)
|
||||
*p = append(q, e)
|
||||
}
|
||||
func (p *pQueue) Pop() interface{} {
|
||||
q := *p
|
||||
last := len(q) - 1
|
||||
e := q[last]
|
||||
*p = q[:last]
|
||||
return e
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/jbarham/primegen.go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
p := primegen.New()
|
||||
|
||||
fmt.Print("First twenty: ")
|
||||
for i := 0; i < 20; i++ {
|
||||
fmt.Print(p.Next(), " ")
|
||||
}
|
||||
fmt.Print("\nBetween 100 and 150: ")
|
||||
p.SkipTo(100)
|
||||
for n := p.Next(); n < 150; n = p.Next() {
|
||||
fmt.Print(n, " ")
|
||||
}
|
||||
p.SkipTo(7700)
|
||||
fmt.Println("\nNumber beween 7,700 and 8,000:", p.Count(8000))
|
||||
p.Reset()
|
||||
for i := 1; i < 1e4; i++ {
|
||||
p.Next()
|
||||
}
|
||||
fmt.Println("10,000th prime:", p.Next())
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
#!/usr/bin/env runghc
|
||||
|
||||
import Data.List
|
||||
import Data.Numbers.Primes
|
||||
import System.IO
|
||||
|
||||
firstNPrimes :: Integer -> [Integer]
|
||||
firstNPrimes n = genericTake n primes
|
||||
|
||||
primesBetweenInclusive :: Integer -> Integer -> [Integer]
|
||||
primesBetweenInclusive lo hi =
|
||||
dropWhile (< lo) $ takeWhile (<= hi) primes
|
||||
|
||||
nthPrime :: Integer -> Integer
|
||||
nthPrime n = genericIndex primes (n - 1) -- beware 0-based indexing
|
||||
|
||||
main = do
|
||||
hSetBuffering stdout NoBuffering
|
||||
putStr "First 20 primes: "
|
||||
print $ firstNPrimes 20
|
||||
putStr "Primes between 100 and 150: "
|
||||
print $ primesBetweenInclusive 100 150
|
||||
putStr "Number of primes between 7700 and 8000: "
|
||||
print $ genericLength $ primesBetweenInclusive 7700 8000
|
||||
putStr "The 10000th prime: "
|
||||
print $ nthPrime 10000
|
||||
|
|
@ -0,0 +1 @@
|
|||
![2,3,5,7] | (nc := 11) | (nc +:= |wheel2345)
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
import Collections # to get the Heap class for use as a Priority Queue
|
||||
record filter(composite, prime) # next composite involving this prime
|
||||
|
||||
procedure main()
|
||||
every writes((primes()\20)||" " | "\n")
|
||||
every p := primes() do if 100 < p < 150 then writes(p," ") else if p >= 150 then break write()
|
||||
every (n := 0, p := primes()) do if 7700 < p < 8000 then n +:= 1 else if p >= 8000 then break write(n)
|
||||
every (i := 1, p := primes()) do if (i+:=1) >= 10000 then break write(p)
|
||||
end
|
||||
|
||||
procedure primes()
|
||||
local wheel2357, nc
|
||||
wheel2357 := [2, 4, 2, 4, 6, 2, 6, 4, 2, 4, 6, 6, 2, 6, 4, 2,
|
||||
6, 4, 6, 8, 4, 2, 4, 2, 4, 8, 6, 4, 6, 2, 4, 6,
|
||||
2, 6, 6, 4, 2, 4, 6, 2, 6, 4, 2, 4, 2, 10, 2, 10]
|
||||
suspend sieve(Heap(,getCompositeField), ![2,3,5.7] | (nc := 11) | (nc +:= |!wheel2357))
|
||||
end
|
||||
|
||||
procedure sieve(pQueue, candidate)
|
||||
local nc
|
||||
if 0 = pQueue.size() then { # 2 is prime
|
||||
pQueue.add(filter(candidate*candidate, candidate))
|
||||
return candidate
|
||||
}
|
||||
while candidate > (nc := pQueue.get()).composite do {
|
||||
nc.composite +:= nc.prime
|
||||
pQueue.add(nc)
|
||||
}
|
||||
pQueue.add(filter(nc.composite+nc.prime, nc.prime))
|
||||
if candidate < nc.composite then { # new prime found!
|
||||
pQueue.add(filter(candidate*candidate, candidate))
|
||||
return candidate
|
||||
}
|
||||
|
||||
end
|
||||
|
||||
# Provide a function for comparing filters in the priority queue...
|
||||
procedure getCompositeField(x); return x.composite; end
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
p:i.20
|
||||
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71
|
||||
(#~ >:&100)i.&.(p:inv) 150
|
||||
101 103 107 109 113 127 131 137 139 149
|
||||
#(#~ >:&7700)i.&.(p:inv) 8000
|
||||
30
|
||||
p:10000-1
|
||||
104729
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
Prime[Range[20]]
|
||||
{2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71}
|
||||
Select[Range[100,150], PrimeQ]
|
||||
{101, 103, 107, 109, 113, 127, 131, 137, 139, 149}
|
||||
PrimePi[8000] - PrimePi[7700]
|
||||
30
|
||||
Prime[10000]
|
||||
104729
|
||||
|
|
@ -0,0 +1,459 @@
|
|||
program prime7;
|
||||
{$IFDEF FPC}
|
||||
{$MODE DELPHI}
|
||||
{$OPTIMIZATION ON,REGVAR,PEEPHOLE,CSE,ASMCSE}
|
||||
{$Smartlink ON}
|
||||
{$CODEALIGN proc=32}
|
||||
{$ELSE}
|
||||
{$APPLICATION CONSOLE}
|
||||
{$ENDIF}
|
||||
uses
|
||||
popcount;
|
||||
const
|
||||
|
||||
InitPrim :array [0..9] of byte = (2,3,5,7,11,13,17,19,23,29);
|
||||
(*
|
||||
{MAXANZAHL = 2*3*5*7*11*13*17*19;*PRIM}
|
||||
MAXANZAHL :array [0..8] of Longint =(2,6,30,210,2310,30030,
|
||||
510510,9699690,223092870);
|
||||
{WIFEMAXLAENGE = 1*2*4*6*10*12*16*18;*PRIM-1}
|
||||
WIFEMAXLAENGE :array [0..8] of longint =(1,2,8,48,480,5760,
|
||||
92160,1658880,36495360);
|
||||
*)
|
||||
BIS = 4;
|
||||
cMaxZahl = 2310;
|
||||
cRepFldLen = 480;
|
||||
|
||||
{Sieve results:
|
||||
one billion -- 50,847,534
|
||||
two billion -- 98,222,287
|
||||
three billion -- 144,449,537
|
||||
four billion -- 189,961,812
|
||||
ten billion -- 455.052.511
|
||||
}
|
||||
MaxZahl = 20*1000*1000;
|
||||
//limit for 32 Bit calc tSievenum = LongWord; 20e9
|
||||
//MaxZahl = High(LongWord) DIV cRepFldLen *cMaxZahl;
|
||||
MAXIMUM = ((MaxZahl-1) DIV cMaxZahl+1)*cMaxZahl;
|
||||
// maximal distance in number wheel
|
||||
MaxMulFac = 14; {array [0..9] of byte= (2,4,6,10,14,22,26,34,40,50);}
|
||||
{Auf Mod 32 = 0 bringen}
|
||||
{MAXSUCHE = MAXIMUM*WIFEMAXLAENGE[BIS]/MAXANZAHl[BIS]}
|
||||
(* div2,div3,*4div15,*8div35,*16div77,*192 div 1001,*3072div17017.. *)
|
||||
MAXSUCHE = ((((MAXIMUM-1) div cMaxZahl+1)*cRepFldLen-1)shr 5+1)shl 5;
|
||||
|
||||
|
||||
type
|
||||
tSievenum = Uint32;// Uint64 doubles run-time in 32 Bit
|
||||
tSegment = record
|
||||
dOfs,
|
||||
dSegment :LongWord;
|
||||
end;
|
||||
tpSegment = ^tSegment;
|
||||
tMulFeld = array [0..MaxMulFac shr 1 -1] of tSegment;
|
||||
tnumberField= array [0..cMaxZahl-1] of Word;
|
||||
tDiffFeld = array [0..{WIFEMAXLAENGE[BIS]}cRepFldLen-1] of byte;
|
||||
tRevIdx = array [0..{WIFEMAXLAENGE[BIS]}cRepFldLen-1] of word;
|
||||
(* numberField as Bit array *)
|
||||
tsearchFld = array [0..MAXSUCHE shr 5-1] of set of 0..31;
|
||||
|
||||
tRecPrime = record
|
||||
rpPrime :tSievenum;
|
||||
rpsvPos,
|
||||
rpOfs,
|
||||
rpSeg :LongWord;
|
||||
end;
|
||||
|
||||
var
|
||||
MulFeld : tMulFeld;
|
||||
searchFld : tsearchFld;
|
||||
number : tnumberField;
|
||||
DiffFld : tDiffFeld;
|
||||
RevIdx : tRevIdx;
|
||||
Quadrat : Uint64;
|
||||
MaxPos : NativeUint;
|
||||
|
||||
const
|
||||
two : Array [0..31] Of LongWord = (
|
||||
$00000001 , $00000002 , $00000004 , $00000008
|
||||
, $00000010 , $00000020 , $00000040 , $00000080
|
||||
, $00000100 , $00000200 , $00000400 , $00000800
|
||||
, $00001000 , $00002000 , $00004000 , $00008000
|
||||
, $00010000 , $00020000 , $00040000 , $00080000
|
||||
, $00100000 , $00200000 , $00400000 , $00800000
|
||||
, $01000000 , $02000000 , $04000000 , $08000000
|
||||
, $10000000 , $20000000 , $40000000 , $80000000
|
||||
) ;
|
||||
|
||||
procedure BuildWheel;
|
||||
{simple sieve of erathothenes only eliminating small primes}
|
||||
var
|
||||
pr,i,j,Ofs : NativeUint;
|
||||
Begin
|
||||
Fillchar(number,SizeOf(number),#0);
|
||||
For i := 0 to BIS do
|
||||
Begin
|
||||
pr := InitPrim[i];
|
||||
j := (High(number) div pr)*pr;
|
||||
repeat
|
||||
number[j] := 1;
|
||||
dec(j,pr);
|
||||
until j <= 0;
|
||||
end;
|
||||
|
||||
i := 1;
|
||||
j := 0;
|
||||
RevIdx[0]:= 1;
|
||||
repeat
|
||||
Ofs :=0;
|
||||
repeat
|
||||
inc(i);
|
||||
inc(ofs);
|
||||
until number[i] = 0;
|
||||
DiffFld[j] := ofs;
|
||||
inc(j);
|
||||
RevIdx[j] := i;
|
||||
until i = High(number);
|
||||
DiffFld[j] := 2;
|
||||
|
||||
//calculate a bitnumber-index into cRepFldLen
|
||||
Fillchar(number,SizeOf(number),#0);
|
||||
Ofs := 1;
|
||||
for i := 0 to cRepFldLen-2 do
|
||||
begin
|
||||
inc(Ofs,DiffFld[i]);
|
||||
number[Ofs] := i+1;
|
||||
end;
|
||||
|
||||
For i := 0 to cRepFldLen-1 do
|
||||
Begin
|
||||
//direct index to Mulfeld
|
||||
j := (DiffFld[i] shr 1) -1;
|
||||
DiffFld[i] := j;
|
||||
end;
|
||||
end;
|
||||
|
||||
function CalcPos(m: Uint64): UINt32;
|
||||
{search right position of m}
|
||||
var
|
||||
i,res : Uint32;
|
||||
Begin
|
||||
res := m div cMaxZahl;
|
||||
i := m mod cMaxzahl;
|
||||
while (number[i]= 0) and (i <>1) do
|
||||
begin
|
||||
iF i = 0 THEN
|
||||
begin
|
||||
Dec(res,cRepFldLen);
|
||||
i := cMaxzahl;
|
||||
end;
|
||||
dec(i);
|
||||
end; {while}
|
||||
CalcPos := res *cRepFldLen +number[i];
|
||||
end;
|
||||
|
||||
procedure MulTab(searchPr:Nativeint);
|
||||
var
|
||||
k,Segment,Segment0,Rest,Rest0: NativeUint;
|
||||
Begin
|
||||
{Multiplikationstabelle der Differenzen}
|
||||
searchPr := searchPr+searchPr;
|
||||
Segment0 := searchPr div cMaxzahl;
|
||||
|
||||
Rest0 := searchPr-Segment0*cMaxzahl;
|
||||
Segment0 := Segment0 * cRepFldLen;
|
||||
|
||||
Segment := Segment0;
|
||||
Rest := Rest0;
|
||||
|
||||
with MulFeld[0] do
|
||||
begin
|
||||
dOfs := Rest0;
|
||||
dSegment:= Segment0;
|
||||
end;
|
||||
|
||||
for k := 1 to MaxMulFac shr 1-1 do
|
||||
begin
|
||||
Segment := Segment+Segment0;
|
||||
Rest := Rest+Rest0;
|
||||
IF Rest >= cMaxzahl then
|
||||
Begin
|
||||
Rest:= Rest-cMaxzahl;
|
||||
Segment := Segment+cRepFldLen;
|
||||
end;
|
||||
with MulFeld[k] do
|
||||
begin
|
||||
dOfs := Rest;
|
||||
dSegment:= Segment;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure CalcSqrOfs(searchPr:NativeUint;out
|
||||
Segment,Ofs :tSievenum);
|
||||
Begin
|
||||
Segment := Quadrat div cMaxZahl;
|
||||
Ofs := Quadrat-Uint64(Segment)*cMaxZahl; //ofs Mod cMaxZahl
|
||||
Segment := Segment*cRepFldLen;
|
||||
end;
|
||||
|
||||
procedure Sieben(var sf:tsearchFld;searchPr,MulPos:NativeUint);
|
||||
//for big sieve Segment,Position,k need to be Uint64
|
||||
var
|
||||
Ofs,Segment,Position,k : tSievenum;//NativeUint;
|
||||
p : pLongWord;
|
||||
Begin
|
||||
MulTab(searchPr);
|
||||
CalcSqrOfs(searchPr,Segment,Ofs);
|
||||
Position := Segment+number[ofs];
|
||||
|
||||
{Primzahlen ausstreichen}
|
||||
repeat
|
||||
k:= MulPos+1;
|
||||
IF k >= cRepFldLen then
|
||||
dec(k,k);//=0;
|
||||
mulpos := k;
|
||||
k := DiffFld[k];
|
||||
With MulFeld[k] do
|
||||
begin
|
||||
k:= Ofs+dOfs;
|
||||
Segment := Segment+dSegment;
|
||||
end;
|
||||
|
||||
If k >= cMaxZahl then
|
||||
begin
|
||||
k := k-cMaxZahl;
|
||||
Segment := Segment+cRepFldLen;
|
||||
end;
|
||||
Ofs := k;
|
||||
k := Segment+number[k];
|
||||
p := @sf[Position shr 5];
|
||||
// exclude(searchFld[Position shr 5],Position and 31);
|
||||
p^ := p^ OR two[Position and 31];
|
||||
IF k > Position then
|
||||
Position := k//number[Ofs]+Segment;
|
||||
else
|
||||
//case of overflow try 2E10 with 32-Bit
|
||||
Break;
|
||||
until Position >= MaxPos;
|
||||
end;
|
||||
|
||||
procedure SieveAll;
|
||||
var
|
||||
i,
|
||||
searchPr,
|
||||
PrimPos,
|
||||
srPrPos : NativeUint;
|
||||
Begin
|
||||
BuildWheel;
|
||||
MaxPos := CalcPos(MaxZahl);
|
||||
{start of prime sieving}
|
||||
fillchar(searchFld,SizeOf(searchFld),#0);
|
||||
{the first prime}
|
||||
srPrPos := 0;
|
||||
PrimPos := 0;
|
||||
searchPr := 1;
|
||||
Quadrat := searchPr;
|
||||
repeat
|
||||
{next prime}
|
||||
inc(srPrPos);
|
||||
i := 2*(DiffFld[PrimPos]+1);
|
||||
//binom (a+b)^2; a^2 already known
|
||||
Quadrat := Quadrat+(2*searchPr+i)*i;
|
||||
inc(searchPr,i);
|
||||
IF Quadrat > MAXIMUM THEN
|
||||
BREAK;
|
||||
{if searchPr == prime then sieve with searchPr}
|
||||
if NOT((srPrPos and 31) in searchFld[srPrPos shr 5] )then
|
||||
Sieben(searchFld,searchPr,PrimPos);
|
||||
inc(PrimPos);
|
||||
if PrimPos = cRepFldLen then
|
||||
dec(PrimPos,PrimPos);// := 0;
|
||||
until false;
|
||||
end;
|
||||
|
||||
function InitRecPrime(pr: tSievenum):tRecPrime;
|
||||
var
|
||||
svPos,sg : LongWord;
|
||||
Begin
|
||||
svPos := CalcPos(pr);
|
||||
sg := svPos DIV cRepFldLen;
|
||||
with result do
|
||||
Begin
|
||||
rpsvPos := svPos;
|
||||
rpSeg := sg;
|
||||
rpOfs := svPos - sg*cRepFldLen;
|
||||
rpPrime := RevIdx[rpOfs]+ sg*cMaxZahl;
|
||||
end;
|
||||
end;
|
||||
|
||||
function InitPrimeSvPos(svPos: LongWord):tRecPrime;
|
||||
var
|
||||
sg : LongWord;
|
||||
Begin
|
||||
sg := svPos DIV cRepFldLen;
|
||||
with result do
|
||||
Begin
|
||||
rpsvPos := svPos;
|
||||
rpSeg := sg;
|
||||
rpOfs := svPos - sg*cRepFldLen;
|
||||
rpPrime := RevIdx[rpOfs]+ sg*cMaxZahl;
|
||||
end;
|
||||
end;
|
||||
|
||||
Procedure NextPrime(var pr: tRecPrime);
|
||||
var
|
||||
ofs,svPos : LongWord;
|
||||
Begin
|
||||
with pr do
|
||||
Begin
|
||||
svPos := rpsvPos;
|
||||
Ofs := rpOfs;
|
||||
repeat
|
||||
inc(svPos);
|
||||
if svPos > MaxPos then
|
||||
EXIT;
|
||||
inc(Ofs);
|
||||
IF Ofs >= cRepFldLen then
|
||||
Begin
|
||||
ofs := 0;
|
||||
inc(rpSeg,cRepFldLen);
|
||||
end;
|
||||
until NOT((svPos and 31) in searchFld[svPos shr 5] );
|
||||
rpPrime := rpSeg*cMaxZahl+RevIdx[Ofs];
|
||||
rpSvPos := svPos;
|
||||
rpOfs := Ofs;
|
||||
end;
|
||||
end;
|
||||
|
||||
function GetNthPrime(n: LongWord):tRecPrime;
|
||||
var
|
||||
i,cnt : longWord;
|
||||
Begin
|
||||
IF n > MaxPos then
|
||||
EXIT;
|
||||
|
||||
i := 0;
|
||||
cnt := Bis;
|
||||
For i := 0 to n shr 5 do
|
||||
inc(cnt,PopCnt(NOT(Uint32(searchFld[i]))));
|
||||
i := n shr 5+1;
|
||||
while cnt < n do
|
||||
Begin
|
||||
inc(cnt,PopCnt(NOT(Uint32(searchFld[i]))));
|
||||
inc(i);
|
||||
end;
|
||||
dec(i);
|
||||
dec(cnt,PopCnt(NOT(Uint32(searchFld[i]))));
|
||||
result := InitPrimeSvPos(i*32-1);
|
||||
while cnt < n do
|
||||
Begin
|
||||
NextPrime(Result);
|
||||
inc(cnt);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure ShowPrimes(loLmt,HiLmt: NativeInt);
|
||||
var
|
||||
p1 :tRecPrime;
|
||||
Begin
|
||||
IF HiLmt < loLmt then
|
||||
exit;
|
||||
p1 := InitRecPrime(loLmt);
|
||||
while p1.rpPrime < LoLmt do
|
||||
NextPrime(p1);
|
||||
repeat
|
||||
write(p1.rpPrime,' ');
|
||||
NextPrime(p1);
|
||||
until p1.rpPrime > HiLmt;
|
||||
writeln;
|
||||
end;
|
||||
|
||||
function CountPrimes(loLmt,HiLmt: NativeInt):LongWord;
|
||||
var
|
||||
p1 :tRecPrime;
|
||||
Begin
|
||||
result := 0;
|
||||
IF HiLmt < loLmt then
|
||||
exit;
|
||||
|
||||
p1 := InitRecPrime(loLmt);
|
||||
while p1.rpPrime < LoLmt do
|
||||
NextPrime(p1);
|
||||
repeat
|
||||
inc(result);
|
||||
NextPrime(p1);
|
||||
until p1.rpPrime > HiLmt;
|
||||
end;
|
||||
|
||||
procedure WriteCntSmallPrimes(n: NativeInt);
|
||||
var
|
||||
i, p,prPos,svPos : nativeUint;
|
||||
Begin
|
||||
dec(n);
|
||||
IF n < 0 then
|
||||
EXIT;
|
||||
write('First ',n+1,' primes ');
|
||||
IF n < Bis then
|
||||
Begin
|
||||
For i := 0 to n do
|
||||
write(InitPrim[i]:3);
|
||||
end
|
||||
else
|
||||
Begin
|
||||
For i := 0 to BIS do
|
||||
write(InitPrim[i],' ');
|
||||
dec(n,Bis);
|
||||
|
||||
svPos := 0;
|
||||
PrPos := 0;
|
||||
p := 1;
|
||||
while n> 0 do
|
||||
Begin
|
||||
{next prime}
|
||||
inc(svPos);
|
||||
inc(p,2*(DiffFld[prPos]+1));
|
||||
if NOT((svPos and 31) in searchFld[svPos shr 5] )then
|
||||
Begin
|
||||
write(p,' ');
|
||||
dec(n);
|
||||
end;
|
||||
inc(prPos);
|
||||
if prPos = cRepFldLen then
|
||||
dec(prPos,prPos);// := 0;
|
||||
end;
|
||||
end;
|
||||
writeln;
|
||||
end;
|
||||
|
||||
var
|
||||
Anzahl :Uint64;
|
||||
i : NativeUint;
|
||||
Begin
|
||||
SieveAll;
|
||||
|
||||
i := 0;
|
||||
Anzahl := BIS+1;
|
||||
//MaxPos = res *cRepFldLen +number[i];
|
||||
For i := 0 to MaxPos shr 5-1 do
|
||||
inc(Anzahl,PopCnt(NOT(Uint32(searchFld[i]))));
|
||||
i := MaxPos AND 31;
|
||||
dec(i);
|
||||
while i>0 do
|
||||
Begin
|
||||
IF Not(i in searchFld[MaxPos shr 5]) then
|
||||
inc(Anzahl);
|
||||
dec(i);
|
||||
end;
|
||||
// Writeln('Bis ',MaxZahl,' sind es ',Anzahl,' Primzahlen');
|
||||
WriteCntSmallPrimes(20);
|
||||
write('Primes between 100 and 150: ');
|
||||
ShowPrimes(100,150);
|
||||
write('Number of primes between 7700 and 8000 ');
|
||||
Writeln(CountPrimes(7700,8000));
|
||||
i := 100;
|
||||
repeat
|
||||
Writeln('the ',i, ' th prime ',GetNthPrime(i).rpPrime);
|
||||
i := i * 10;
|
||||
until i> 1000000;
|
||||
end.
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
my @primes := gather for 1 .. * { .take if $_.is-prime }
|
||||
|
||||
say "The first twenty primes:\n ", "[{@primes[^20].fmt("%d", ', ')}]";
|
||||
say "The primes between 100 and 150:\n ", "[{@primes.&between(100, 150).fmt("%d", ', ')}]";
|
||||
say "The number of primes between 7,700 and 8,000:\n ", +@primes.&between(7700, 8000);
|
||||
say "The 10,000th prime:\n ", @primes[9999];
|
||||
|
||||
sub between (@p, $l, $u) {
|
||||
gather for @p { .take if $l < $_ < $u; last if $_ >= $u }
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
use Math::Prime::Util qw(nth_prime prime_count primes);
|
||||
# Direct solutions.
|
||||
# primes([start],end) returns an array reference with all primes in the range
|
||||
# prime_count([start],end) uses sieving or LMO to return fast prime counts
|
||||
# nth_prime(n) does just that. It runs quite fast for native size inputs.
|
||||
say "First 20: ", join(" ", @{primes(nth_prime(20))});
|
||||
say "Between 100 and 150: ", join(" ", @{primes(100,150)});
|
||||
say prime_count(7700,8000), " primes between 7700 and 8000";
|
||||
say "${_}th prime: ", nth_prime($_) for map { 10**$_ } 1..8;
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
use Math::Prime::Util "prime_iterator_object";
|
||||
my $it = prime_iterator_object;
|
||||
say "First 20: ", join(" ", map { $it->iterate() } 1..20);
|
||||
$it->seek_to_value(100);
|
||||
print "Between 100 and 150:";
|
||||
print " ", $it->iterate() while $it->value() <= 150;
|
||||
print "\n";
|
||||
$it->seek_to_value(7700);
|
||||
my $c = 0;
|
||||
$c++ while $it->iterate() <= 8000;
|
||||
say "$c primes between 7700 and 8000";
|
||||
say "${_}th prime: ", $it->ith($_) for map { 10**$_ } 1..8;
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
use Math::Prime::Util qw/forprimes/;
|
||||
use Math::Prime::Util::PrimeArray;
|
||||
tie my @primes, 'Math::Prime::Util::PrimeArray';
|
||||
|
||||
say "First 20: @primes[0..19]"; # Slice from the tied array
|
||||
print "Between 100 and 150: "; forprimes { print " $_"; } 100,150; print "\n";
|
||||
# Count with forprimes
|
||||
my $c = 0;
|
||||
forprimes { $c++ } 7700,8000;
|
||||
print "$c primes between 7700 and 8000\n";
|
||||
# The tied array tries to do the right thing -- sieve a window if it sees
|
||||
# forward or backward iteration, and nth_prime if it looks like random access.
|
||||
say "${_}th prime: ", $primes[$_-1] for map { 10**$_ } 1..8;
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
use bigint;
|
||||
use Math::Prime::Util qw/forprimes prime_get_config/;
|
||||
warn "No GMP, expect slow results\n" unless prime_get_config->{gmp};
|
||||
my $n = 10**200;
|
||||
forprimes { say $_-$n } $n,$n+1000;
|
||||
|
|
@ -0,0 +1 @@
|
|||
islice(count(7), 0, None, 2)
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
from __future__ import print_function
|
||||
from prime_decomposition import primes
|
||||
from itertools import islice
|
||||
|
||||
|
||||
def p_range(lower_inclusive, upper_exclusive):
|
||||
'Primes in the range'
|
||||
for p in primes():
|
||||
if p >= upper_exclusive: break
|
||||
if p >= lower_inclusive: yield p
|
||||
|
||||
if __name__ == '__main__':
|
||||
print('The first twenty primes:\n ', list(islice(primes(),20)))
|
||||
print('The primes between 100 and 150:\n ', list(p_range(100, 150)))
|
||||
print('The ''number'' of primes between 7,700 and 8,000:\n ', len(list(p_range(7700, 8000))))
|
||||
print('The 10,000th prime:\n ', next(islice(primes(),10000-1, 10000)))
|
||||
1
Task/Extensible-prime-generator/README
Normal file
1
Task/Extensible-prime-generator/README
Normal file
|
|
@ -0,0 +1 @@
|
|||
Data source: http://rosettacode.org/wiki/Extensible_prime_generator
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
/*REXX program finds primes using an extendible prime number generator.*/
|
||||
parse arg f .; if f=='' then f=20 /*allow specifying # for 1 ──► F.*/
|
||||
call primes f; do j=1 for f; $=$ @.j; end
|
||||
say 'first' f 'primes are:' $
|
||||
say
|
||||
call primes -150; do j=100 to 150; if !.j==0 then iterate; $=$ j; end
|
||||
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
|
||||
say 'the number of primes between 7700 and 8000 (inclusive) is:' words($)
|
||||
say
|
||||
call primes 10000
|
||||
say 'the 10000th prime is:' @.10000
|
||||
exit /*stick a fork in it, we're done.*/
|
||||
/*──────────────────────────────────PRIMES subroutine───────────────────*/
|
||||
primes: procedure expose !. s. @. $ #; parse arg H . 1 m .,,$; H=abs(H)
|
||||
if symbol('!.0')=='LIT' then /*1st time here? 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 number of primes.*/
|
||||
end /* [↑] done with building low Ps*/
|
||||
neg= m<0 /*Neg? Request is for a P value.*/
|
||||
if neg then if H<=@.# then return /*Have a high enough P already?*/
|
||||
else nop /*used to match the above THEN. */
|
||||
else if H<=# then return /*Have a enough primes already ? */
|
||||
/*─────────────────────────────────────── [↓] gen more P's within range*/
|
||||
do j=@.#+2 by 2 /*find primes until have H Primes*/
|
||||
if j//3 ==0 then iterate /*is J divisible by three? */
|
||||
if right(j,1)==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 seven 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 divisible by P? Not prime.*/
|
||||
end /*k*/ /* [↑] divide by odd primes √j.*/
|
||||
#=#+1 /*bump number of primes found. */
|
||||
@.#=j; s.#=j*j; !.j=1 /*assign to sparse array; prime².*/
|
||||
if neg then if H<=@.# then leave /*do we have 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 'til nuff*/
|
||||
return /*return to invoker with more Ps.*/
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
#lang racket
|
||||
;; Using the prime functions from:
|
||||
(require math/number-theory)
|
||||
|
||||
(displayln "Show the first twenty primes.")
|
||||
(next-primes 1 20)
|
||||
|
||||
(displayln "Show the primes between 100 and 150.")
|
||||
;; Note that in each of the in-range filters I "add1" to the stop value, so that (in this case) 150 is
|
||||
;; considered. I'm pretty sure it's not prime... but technology moves so fast nowadays that things
|
||||
;; might have changed!
|
||||
(for/list ((i (sequence-filter prime? (in-range 100 (add1 150))))) i)
|
||||
|
||||
(displayln "Show the number of primes between 7,700 and 8,000.")
|
||||
;; (for/sum (...) 1) counts the values in a sequence
|
||||
(for/sum ((i (sequence-filter prime? (in-range 7700 (add1 8000))))) 1)
|
||||
|
||||
(displayln "Show the 10,000th prime.")
|
||||
(nth-prime (sub1 10000)) ; (nth-prime 0) => 2
|
||||
|
||||
;; If a languages in-built prime generator is extensible or is guaranteed to generate primes up to a
|
||||
;; system limit, (2^31 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).
|
||||
;;
|
||||
;; Full details in:
|
||||
;; [[http://docs.racket-lang.org/math/number-theory.html?q=prime%3F#%28part._primes%29]]
|
||||
;; When reading the manual, note that "Integer" and "Natural" are unlimited (or bounded by whatever
|
||||
;; big number representation there is (and the computational complexity of the work being asked).
|
||||
(define 2^256 (expt 2 256))
|
||||
2^256
|
||||
(next-prime 2^256)
|
||||
;; (Oh, and this is a 64-bit laptop, I left my 256-bit PC in the office.)
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
require "prime"
|
||||
|
||||
puts Prime.take(20).join(", ")
|
||||
puts Prime.each(150).drop_while{|pr| pr < 100}.join(", ")
|
||||
puts Prime.each(8000).drop_while{|pr| pr < 7700}.count
|
||||
puts Prime.take(10_000).last
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
$ include "seed7_05.s7i";
|
||||
|
||||
const func boolean: isPrime (in integer: number) is func
|
||||
result
|
||||
var boolean: result is FALSE;
|
||||
local
|
||||
var integer: count is 2;
|
||||
begin
|
||||
if number = 2 then
|
||||
result := TRUE;
|
||||
elsif number > 2 then
|
||||
while number rem count <> 0 and count * count <= number do
|
||||
incr(count);
|
||||
end while;
|
||||
result := number rem count <> 0;
|
||||
end if;
|
||||
end func;
|
||||
|
||||
var integer: currentPrime is 1;
|
||||
var integer: primeNum is 0;
|
||||
|
||||
const func integer: getPrime is func
|
||||
result
|
||||
var integer: prime is 0;
|
||||
begin
|
||||
repeat
|
||||
incr(currentPrime);
|
||||
until isPrime(currentPrime);
|
||||
prime := currentPrime;
|
||||
incr(primeNum);
|
||||
end func;
|
||||
|
||||
const proc: main is func
|
||||
local
|
||||
var integer: aPrime is 0;
|
||||
var integer: count is 0;
|
||||
begin
|
||||
write("First twenty primes:");
|
||||
while primeNum < 20 do
|
||||
write(" " <& getPrime);
|
||||
end while;
|
||||
writeln;
|
||||
repeat
|
||||
aPrime := getPrime;
|
||||
until aPrime >= 100;
|
||||
write("Primes between 100 and 150:");
|
||||
while aPrime <= 150 do
|
||||
write(" " <& aPrime);
|
||||
aPrime := getPrime;
|
||||
end while;
|
||||
writeln;
|
||||
repeat
|
||||
aPrime := getPrime;
|
||||
until aPrime >= 7700;
|
||||
while aPrime <= 8000 do
|
||||
incr(count);
|
||||
aPrime := getPrime;
|
||||
end while;
|
||||
writeln("Number of primes between 7,700 and 8,000: " <& count);
|
||||
repeat
|
||||
aPrime := getPrime;
|
||||
until primeNum = 10000;
|
||||
writeln("The 10,000th prime: " <& getPrime);
|
||||
end func;
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
package require Tcl 8.6
|
||||
|
||||
# An iterative version of the Sieve of Eratosthenes.
|
||||
# Effective limit is the size of memory.
|
||||
coroutine primes apply {{} {
|
||||
yield
|
||||
while 1 {yield [coroutine primes_[incr p] apply {{} {
|
||||
yield [info coroutine]
|
||||
set plist {}
|
||||
for {set n 2} true {incr n} {
|
||||
set found 0
|
||||
foreach p $plist {
|
||||
if {$n%$p==0} {
|
||||
set found 1
|
||||
break
|
||||
}
|
||||
}
|
||||
if {!$found} {
|
||||
lappend plist $n
|
||||
yield $n
|
||||
}
|
||||
}
|
||||
}}]}
|
||||
}}
|
||||
|
||||
set p [primes]
|
||||
for {set primes {}} {[llength $primes] < 20} {} {
|
||||
lappend primes [$p]
|
||||
}
|
||||
puts 1st20=[join $primes ,]
|
||||
rename $p {}
|
||||
|
||||
set p [primes]
|
||||
for {set primes {}} {[set n [$p]] <= 150} {} {
|
||||
if {$n >= 100 && $n <= 150} {
|
||||
lappend primes $n
|
||||
}
|
||||
}
|
||||
puts 100-150=[join $primes ,]
|
||||
rename $p {}
|
||||
|
||||
set p [primes]
|
||||
for {set count 0} {[set n [$p]] <= 8000} {} {
|
||||
incr count [expr {$n>=7700 && $n<=8000}]
|
||||
}
|
||||
puts count7700-8000=$count
|
||||
rename $p {}
|
||||
|
||||
set p [primes]
|
||||
for {set count 0} {$count < 10000} {incr count} {
|
||||
set prime [$p]
|
||||
}
|
||||
puts prime10000=$prime
|
||||
rename $p {}
|
||||
Loading…
Add table
Add a link
Reference in a new issue