Browse Source

Adding algorithm to generate primes in a stream, i.e., starting from m and going to n.

master
Charles Reid 8 years ago
parent
commit
31b68f5d12
  1. 134
      501/PrimeStream.java

134
501/PrimeStream.java

@ -0,0 +1,134 @@ @@ -0,0 +1,134 @@
import java.math.BigInteger;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Set;
import java.util.HashSet;
import java.util.BitSet;
public class PrimeStream {
public static void main(String[] args) {
System.out.println( primesRange(100,200,10) );
}
public static List<Long> primesRange(long left, long right, int delta) {
// Return this
ArrayList<Long> result = new ArrayList<Long>();
boolean[] sieve = new boolean[delta-1];
List<Integer> Ps = primeSieve((int)(Math.sqrt(right)));
Ps.remove(Ps.indexOf(2));
//System.out.println(Ps);
List<Integer> Qs = new ArrayList<Integer>();
for(int i=0; i<Ps.size(); i++ ) {
Qs.add( qInit(left, Ps.get(i)) );
}
//System.out.println(Qs);
while(left < right) {
// Assume everybody prime
for(int k=0; k<(delta-1); k++) {
sieve[k] = true;
}
// Cross out multiple of each prime
for(int i=0; i<Ps.size(); i++) {
Integer p = Ps.get(i);
Integer q = Qs.get(i);
System.out.println("------------");
System.out.println("Prime p = "+p);
System.out.println("Left = "+(left+1));
System.out.println("q = "+q);
for(int j=q; j<(delta-1); j+=p) {
System.out.println("j = "+j);
if(sieve[j]) {
System.out.println("Eliminating candidate = "+(left+1+2*j)+" from primes list, multiple of "+p);
}
sieve[j] = false;
}
}
for(int k=0; k<Ps.size(); k++ ) {
Qs.set(k, qReset(Ps.get(k),Qs.get(k),delta) );
}
// Have knocked out non-primes, so gather the primes
long t = left+1;
for(int i=0; i<delta-1; i++) {
// t ends at right
if(sieve[i]) {
result.add(t);
}
t+=2;
}
left += 2*delta;
}
return result;
}
protected static int qInit(long left, int p) {
long plong = (long)p;
long modOfThis = -(left+p+1)/2;
int j = 1;
while(modOfThis<0) {
modOfThis += j*p;
j*=2;
}
long result = modOfThis%plong;
return (int)(result);
}
protected static int qReset(int p, int q, int delta) {
int result = (q-delta)%p;
int j = 1;
while(result < 0) {
result += j*p;
}
return result;
}
/** Find all prime numbers below n.
*/
public static List<Integer> primeSieve(int n) {
// initially assume all integers are prime
boolean[] isPrime = new boolean[n+1];
for (int i = 2; i <= n; i++) {
isPrime[i] = true;
}
// mark non-primes <= n using Sieve of Eratosthenes
for (int factor = 2; factor*factor <= n; factor++) {
// if factor is prime, then mark multiples of factor as nonprime
// suffices to consider mutiples factor, factor+1, ..., n/factor
if (isPrime[factor]) {
for (int j = factor; factor*j <= n; j++) {
isPrime[factor*j] = false;
}
}
}
// Add primes to list
ArrayList<Integer> primes = new ArrayList<Integer>();
int nprimes = 0;
for(int k=2; k<=n; k++) {
if(isPrime[k]) {
primes.add(k);
nprimes++;
}
}
return primes;
}
}
Loading…
Cancel
Save