Skip to content

Add eratosthenes sieve method for finding primes below given number #672

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@
* [Prime Factoriziation](https://github.com/TheAlgorithms/C/blob/master/misc/prime_factoriziation.c)
* [Quartile](https://github.com/TheAlgorithms/C/blob/master/misc/quartile.c)
* [Rselect](https://github.com/TheAlgorithms/C/blob/master/misc/rselect.c)
* [Sieve Of Eratosthenes](https://github.com/TheAlgorithms/C/blob/master/misc/sieve_of_eratosthenes.c)
* [Strong Number](https://github.com/TheAlgorithms/C/blob/master/misc/strong_number.c)
* [Sudoku Solver](https://github.com/TheAlgorithms/C/blob/master/misc/sudoku_solver.c)
* [Tower Of Hanoi](https://github.com/TheAlgorithms/C/blob/master/misc/tower_of_hanoi.c)
Expand Down
72 changes: 72 additions & 0 deletions misc/sieve_of_eratosthenes.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/**
* @file
* @brief Get list of prime numbers using [Sieve of
* Eratosthenes](https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes)
* @details
* Sieve of Eratosthenes is an algorithm that finds all the primes
* between 2 and N.
*
* Time Complexity : \f$O(N \cdot\log \log N)\f$
* <br/>Space Complexity : \f$O(N)\f$
*
*/

#include <assert.h> /// for 'assert' in 'test' function
#include <stdbool.h> /// for 'bool' type in 'sieve' and 'test' function
#include <stdlib.h> /// for 'calloc' in 'sieve' function
#include <string.h> /// for 'memset' in 'sieve' function

/**
* Return all primes between 2 and the given number
* @param N the largest number to be checked for primality
* @return is_prime a dynamically allocated array of `N + 1` booleans identifying if `i`^th number is a prime or not
*/
bool* sieve(int N)
{
bool* primep = calloc(N+1, 1);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dynamically allocated memory must be freeed.
In this case, a note should be added to the function that the function free() must be called on the output pointer after its use.

For example, on line# 48, pointer to a new memory is returned. Hence, before the end of that function, there must be a free(primep);

memset(primep, true, N+1);
primep[0] = false; //0 is not a prime number
primep[1] = false; //1 is not a prime number

int i, j;
for (i=2; i!=N/2; ++i)// i!=N+1 also works
for (j=2; j<=N/i; ++j)// i*j <= N also works
primep[i*j] = false;

return primep;
}

/**
* @brief Test function
* @return void
*/
static void test()
{
/* all the prime numbers less than 100 */
int primers[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41,
43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97};
bool* primep = sieve(100);
for (size_t i = 0, size = sizeof(primers) / sizeof(primers[0]); i < size;
++i)
{
assert(primep[primers[i]]);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the correct loop check would be:

for (size_t j = 0, p = 0; j < 100; j++) 
{
  if (j == primers[p]) // j is a known prime number
  {
      assert(prime[j]);
      p++; // this variable is used to keep a track of the index of known prime numbers array
  } else { // j is a known composite number
      assert(!prime[j]);
  }
}

This will check that your function ensures that both primes and composites are classified correctly.

}

/* Example Non-prime numbers */
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good code :)
but becomes redundant after the above suggested loop. You can keep this loop as well - I like it as it is a good exercise

int nonPrimers[] = {4, 6, 8, 9, 10, 12, 16, 51};
for (size_t i = 0, size = sizeof(nonPrimers) / sizeof(nonPrimers[0]);
i < size; ++i)
{
assert(!primep[nonPrimers[i]]);
}
}

/**
* @brief Driver Code
* @return 0 on exit
*/
int main()
{
test();
return 0;
}