Legendre’s Conjecture: Concept, Algorithm, Implementation in C++


The Legendre’s Conjecture states that at least one prime number always exists between two consecutive natural numbers' squares.

Mathematically, there is always a prime number p between any two numbers n2 and (n+1)2. n is a natural number.

A conjecture means a conclusion that doesn't has mathematical proof. Hence, Legendre's Conjecture is just a statement with no mathematical proof.

Problem Statement

For a number n, print the number of primes in the range of n2 to (n+1)2 from 1 to n.

Examples

Input: 4
Output: 
For i = 1: Total primes in the range 1 and 4 = 2
For i = 2: Total primes in the range 4 and 9 = 2
For i = 3: Total primes in the range 9 and 16 = 2
For i = 4: Total primes in the range 16 and 25 = 3

Explanation

For i =1, n2 =1, and (n+1)2 = 4.

The prime numbers in this range are 2 and 3.

For i = 2, n2 = 4, and (n+1)2 = 9.

The prime numbers in this range are 5 and 7.

For i = 3, n2 = 9, and (n+1)2 = 16.

The prime numbers in this range are 11 and 13.

For i = 4, n2 = 16, and (n+1)2 = 25.

The prime numbers in this range are 17, 19, and 23.

Approach

  • Create a variable count to maintain the number of primes.

  • Start a loop from i = 1 to n.

  • Start another loop from j = i^2 to j = (i+1)2.

  • For each j, check if it is a prime number by dividing it by numbers from 2 to the square root of j.

  • If j is a prime number, increase the value of the count.

  • Print count for each i.

Example

Below is a C++ program to find the number of prime numbers between squares of two consecutive natural numbers.

#include <bits/stdc++.h>
using namespace std;
//This function checks if a number is prime or not
bool prime(int n){
   if(n==1){
      return false;
   }
   //Check for the factors of n.
   for (int i = 2; i * i <= n; i++)
      if (n % i == 0)
         return false;
      //If no factor other than 1, and the number, then return true.
      return true;
}

//This function prints the number of primes
void legendre_conjecture(int n){
   //count of prime numbers for each number from 1 to n.
   int count;
   
   for(int i=1;i<=n;i++){
      count=0;  
      //Check from i^2 to (i+1)^2.
      for(int j=i*i;j<=((i+1)*(i+1));j++){
         //If prime, increase the count.
         if(prime(j)){
            count++;
         }
      }
      //Print the number of prime numbers from i^2 to (i+1)^2
      cout<<"For i: "<<i<<" "<<"Total primes in the range"<<" "<<(i*i)<<" "<<"and"<<" "<<(i+1)*(i+1)<<" "<<"="<<" "<<count<<endl;
   }
}
int main(void){
   int n = 5;
   cout<<"Value of n: 5"<<endl;
   //Function call.
   legendre_conjecture(n);
   return 0;
}

Output

Value of n: 5
For i: 1 Total primes in the range 1 and 4 = 2
For i: 2 Total primes in the range 4 and 9 = 2
For i: 3 Total primes in the range 9 and 16 = 2
For i: 4 Total primes in the range 16 and 25 = 3
For i: 5 Total primes in the range 25 and 36 = 2

The program above will work for small inputs but will be inefficient for larger ones.

Thus, to optimize it, we will use the Sieve of Eratosthenes technique.

The sieve of Eratosthenes technique finds prime numbers by sieving out the undesirable outputs.

Example: (Optimized approach using Sieve of Eratosthenes technique)

Below is a C++ Program to find primes between n^2 and (n+1)^2 using Sieve of Eratosthenes.

#include <bits/stdc++.h>
using namespace std;
#define size 10001

//This function uses the sieve of the Eratosthenes technique
//to sieve the non primes and then stores the count of
//number of primes from 0 to i in count[i].
void find_primes(vector<int>&count){
   
   //vector to sieve out the non primes
   //initially mark every number as prime
   vector<bool>sieve(size, true);
   for (int i = 2; i * i < size; i++) {
   
      if (sieve[i] == true) {
         //Mark all the multiples as false.
         for (int j = i * 2; j < size; j += i)
         sieve[j] = false;
      }
   }
   //count[i] stores the number of primes from 0 to i.
   count[0] = 0;
   count[1] = 0;
   for (int i = 2; i < size; i++) {
      count[i] = count[i - 1];
      if (sieve[i])
      count[i]++;
   }
}

//This function finds total primes in the given range
int count_primes(int s, int e, vector<int>count){
   return count[e] - count[s - 1];
}
int main(void){

   //count vector will store the count of primes
   vector<int> count(size);
   
   //Function call to sieve out all the nonprimes
   // and store the number of primes in the count vector
   find_primes(count);
   int n = 5;
   cout<<"Value of n:  5"<<endl;
   int start, end;
   for(int i=1;i<=n;i++){
      start=i*i;
      end=(i+1)*(i+1);
      cout<<"For i: "<<i<<" "<<"Total primes in the range"<<" "<<start<<" "<<"and"<<" "<<end<<" "<<"="<<" "<<count_primes(start,end,count)<<endl;
   }
   return 0;
}

Output

Value of n:  5
For i: 1 Total primes in the range 1 and 4 = 2
For i: 2 Total primes in the range 4 and 9 = 2
For i: 3 Total primes in the range 9 and 16 = 2
For i: 4 Total primes in the range 16 and 25 = 3
For i: 5 Total primes in the range 25 and 36 = 2

In this article, we understood the concept of Legendre's Conjecture.

We saw some examples and also implemented them using C++ Programming.

We used two approaches, a brute force and the Sieve of Eratosthenes technique.

Updated on: 10-Mar-2023

155 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements