This algorithm is attributed to Eratosthenes, a Greek Mathematician who lived around 200 B.C. - I have described the algorithm and how it works:

A non-zero, postive integer (natural number) is prime if it has no other factors other than 1 and itself. 1 is neither prime nor composite. And 2 is the only even-prime number.

So, multiples of 2 cannot be prime (they have 2 as one of their factors) - Similarly, multiples of 3 also cannot be prime. And so on. So, the idea is multiples of a number cannot be prime.

So, let's consider numbers 1 to 100.

Create an array of 100 numbers and set them all to 1.

Let's start from 2 and mark all the multiples of 2 till 100 as non-prime (a.k.a composite). To do this, let's set the value in the array as 0. [The index should go till 100 / 2]

Then, let's start with 3, and again mark all the multiples of 3 till 100 as non-prime.

Next you reach 4. But, this is 0 already. So, the multiples of 4 should already be set to 0. (Since all multiples of 4 are already multiples of 2) - So ignore 4. [And ignore multiples of those numbers which are already marked as 0]. Then start with 5.

So, how far should you go? Some people choose to go till N / 2 (50) - But this is sub-optimal. It is sufficient if we check for all multiples till square root of N. This is because, any factor greater than SQRT(N) should have a partner that is less than SQRT(N) and hence would have already been marked 0. [Please re-read this para-graph :-) if this sounds confusing]

Now iterate through the array and print all indices where the value is non-zero. Voila! You have generated prime-numbers in

*O*(*n*loglog*n*).I wrote an implementation in Python. It was quite cool :o)

#!/usr/bin/env python

# eratosthenes.py

# Sriram V Iyer

#

# Implements the eratosthenes sieve program

# Initialize an array for 100(+1) 1s

# +1 is to accomodate the cases 2 * 50, ...

l = [ 1 for i in range( 100+1) ]

# make the multiples as 0

[ l.__setitem__(i*j, 0) for i in range(2,10) for j in range(2,(100/i)+1) if l[i] != 0 ]

# print indices of the list that are still 1

print [ i for i in range(2,100) if l[i] == 1 ]

I had a discussion with Tejaswi (my Beceem colleague) on an equivalent C code.

Btw, I used the C/C++ compiler feature that initializes unitialized elements of a a partially initialized array to 0. This way, I changed the polarity to 0 -> Prime and 1 -> Composite in the C code. [This way, I needn't write code to initialize the array to 0]

/*

eratos.c

Sieve of Etatosthenes in C/C++

*/

#include "stdio.h"

#include "math.h"

int main()

{

int N = 100, i = 0, j = 0;

int nArray[100+1] = { 0 };

for( i = 2; i < (sqrt((double)N)); i++ ) {

if(nArray[i] == 1) continue;

for( j = 2; j <= (N/i); j += 1 )

nArray[i * j] = 1;

}

for( i = 2; i <>

if(!nArray[i]) printf( "%d ", i );

}

}

There is one more possible optimization - If you can initialize nArray[4] = 1 in the code before the first loop, you can start the inner loop from 3 :-)

PS:- Looks like the "<<" in cout can confuse blogger. So, I rewrote the program without using cout, endl :-)

## No comments:

Post a Comment