Generating Primes (Part 1)
Generating Primes (Part 1)
(Generating Primes)
by
Jane Alam Jan
1|Page
Document prepared by Jane Alam Jan
Introduction
Before starting the problem, you have to understand how to generate primes. This document
contains some ideas and observations that make a nave algorithm to a better one.
The first task is to know what is a prime. Before advancing, we should understand the word
divisible.
An integer a is said to be divisible by an integer b if we divide a by b, the reminder is zero.
For example 20 is divisible by 5, 26 is divisible by 2, 30 is not divisible by 16. Or we can say
that a is divisible by b if a can be written as b * k where k is an integer.
A prime number is an integer which is divisible by exactly two different integers. By definition,
we see that 1 is not a prime. Since we need two different integers, but 1 is only divisible by 1.
So, 5 is a prime, because it is divisible by two different integers - 1 and 5. 49 is not a prime
because it is divisible by 1, 7 and 49 (three different integers).
The problem is - we have to generate primes from 1 to N. But how to generate primes?
This code will generate all the primes up to 5000. But if we see carefully, we will find that to
check any number we have to divide it by all the numbers smaller to it. So, for 3, we will try to
divide 3 by 2. For 7, we will try to divide it by 2, 3, 4, 5, 6. So, this method is slow, because so
many divisions and checks are required.
2|Page
Document prepared by Jane Alam Jan
3|Page
Document prepared by Jane Alam Jan
So, we can stop checking if we find b for which a/b is less than or equal to b. Cause if we try to
divide by numbers greater than b we will actually repeat the same steps. For 36, (check the lists)
the next number that will be included to list 1 is 9, but 36/9 = 4, which is already in list 1.
Now we have to find b for which a/b is less than or equal to b. If we think mathematically,
b >= a/b
or, b2 >= a
or, b >= sqrt(a)
so, bminimum = sqrt(a)
So, we can update our code.
int N = 5000;
bool isPrime( int i ) {
int sqrtI = int( sqrt( (double) i) );
// dont write "for(int j = 2; j <= sqrt(i); j++)" because sqrt is a slow
// function. So, dont calculate it all the time, calculate it only once
for( int j = 2; j <= sqrtI; j++ ) {
if( i % j == 0 ) // i is divisible by j, so i is not a prime
return false;
}
// No integer less than i, divides i, so, i is a prime
return true;
}
int main() {
for( int i = 2; i <= N; i++ ) {
if( isPrime(i) == true )
printf("%d ", i);
}
return 0;
}
4|Page
Document prepared by Jane Alam Jan
5|Page
Document prepared by Jane Alam Jan
6|Page
Document prepared by Jane Alam Jan
7|Page
Document prepared by Jane Alam Jan
Now, the next number is 5 and the first number that will be colored is 15. But is it necessary to
color 15? Observe that, 15 = 3 * 5, so, we are sure that 15 is colored already. So, we start from
25.
3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51
Now the next number is 7. The first number that will be discarded is 21. But again 21 = 3 * 7, so,
we are sure that 21 is already colored. The next number is 35 (advancing 21 + 2 * 7 = 35), again
35 = 5 * 7, so, its also colored. So, then we have 49, and it is the first number that should be
colored. So, we have
3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51
So, if we have n as a prime, and we want to discard its multiples, then 3 * n is not a good choice,
not even 5 * n, not even (n - 2) * n. The reason is all the numbers mentioned here are colored
already. So, the first number that should be colored is n2. So, we have to check primes up to
square root of N and discard their multiples (say, we want to find primes up to 51, is it necessary
to check the multiples of 11, or higher?). So, the new code will be
int N = 5000, status[5001];
int main() {
int i, j, sqrtN;
for( i = 2; i <= N; i++ ) status[i] = 0;
sqrtN = int( sqrt((double) N )); // have to check primes up to (sqrt(N))
for( i = 3; i <= sqrtN; i += 2 ) {
if( status[i] == 0 ) {
// so, i is a prime, so, discard all the multiples
// j = i * i, because its the first number to be colored
for( j = i * i; j <= N; j += i + i )
status[j] = 1; // status of the multiple is 1
}
}
// print the primes
printf("2 ");
for( i = 3; i <= N; i += 2 ) {
if( status[i] == 0 ) printf("%d ", i);
}
return 0;
}
8|Page
Document prepared by Jane Alam Jan
Discussion
The basic idea of sieve is described here. The code here may have bugs. Before you believe the
codes, try to understand the ideas and convince yourself. Try solving some problems related to
prime numbers.
9|Page
Document prepared by Jane Alam Jan