1

I have written a piece of code below, that ask a user input a number N (3 < N < 1.000.000) odd and count the number of prime number pairs whose sum is equal to N. That code works, but I need to optmize it to make more efficient. When the user inputs a number, I count the number of primes up to this number and store each prime number in a vector, and after that count the number of prime number pairs whose sum is equal to this input.

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void seleciona_primos (int *vet, int n, int raiz){
    int i, j;
        vet[2] = 2;
    for(i=3; i<=n; i+=2){
        vet[i] = i;
    }
    for (i=3; i<= raiz; i+=2){
        if(vet[i]!=0){
            for(j=3; j<=n; j+=2){
                if ((vet[i]!=vet[j]) && (vet[j]%vet[i] == 0)){
                        vet[j]=0;
                }
            }
        }
    }
}

int conta_pares (int *vet, int n){
    int i, j, count=0;
    for (i=3; i<=n; i+=2){
        if(vet[i]!=0){
            for(j=3; j<=n/2; j+=2){
                if((vet[j]!=0) && (vet[i] + vet[j] == n)&& (vet[i]!=0)){
                    //printf("%d ", vet[i]);
                    //printf("%d\n", vet[j]);
                    count++;
                    vet[i] = 0;
                }
            }
        }
    }

    if(vet[n-2]!=0){
        count++;
        }

    return count;
}

int main()
{
    int *vet, n, raiz, i , count;

    scanf("%d", &n);

    vet = (int *) calloc((n+1), sizeof(int));

    raiz =  floor(sqrt(n));

    seleciona_primos(vet, n, raiz);

    count = conta_pares(vet, n);

    printf("%d",count);
    //for(i=3; i<=n; i+=2){
            //if(vet[i]!=0){
                //printf("%d\n", vet[i]);
            //}

    //}
    return 0;
}

  • Try using this, very efficient algorithm for prime numbers: https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes – Filip F. Dec 23 '20 at 17:47
  • This sounds and looks like it's for some competition site. The thing about them is that you almost never can use simple, naive brute-force solutions, they all rely on some kind of dirty tricks. – Some programmer dude Dec 23 '20 at 18:13
  • 1
    Two odd numbers can only sum to an even number. So if N-2 is not prime, there are no solutions. – stark Dec 23 '20 at 18:20

3 Answers3

1

I make an array who countain the prime numbers from 2 to N(1 has only one divisors and 0 has infinites of divisors), and then I check if two numbers from the array equal to N

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

bool Prime(int);

int main()
{
long N;
do
{
   printf("Give me the number of numbers :");
   scanf("%ld",&N);
}while(N<=4||N>1000000);//N must be between 3 & 1000000
int prime[N];
int arr[N];
int j=0;

for(int i=2;i<N;i++)
{
   if(Prime(i)==true)
   {
      prime[j]=i;
      j++;
   }
}
printf("\n\n");
for(int p=0;p<j-1;p++)
{
    for(int q=p+1;q<j;q++)
    {
         if(N==prime[p]+prime[q])
         {
              printf("\n%d = %d + %d \n",N,prime[p],prime[q]);
         }
    }
}
printf("\n\n");
return 0;

}


bool Prime(int n)
{
    for(int i=2;i<=(n/2);i++)
    {
        if(n%i==0)
        {
            return false;
        }
    }
    return true;
}

Example :

Input : N =100;

Output :

100 = 3 + 97

100 = 11 + 89

100 = 17 + 83

100 = 29 + 71

100 = 41 + 59

100 = 47 + 53

MED LDN
  • 684
  • 1
  • 5
  • 10
1

Thank you for all suggestions!! And after some research and tries, I have found the solution that follow bellow:

int isPrime(int x)
{
    int i;
    for(i = 2; i <= sqrt(x); i++)
    {
        if(x%i == 0)
        {
            return 0;
        }
    }
    return 1;
}


int main()
{

   int i, count = 0, n ;

    scanf("%d", &n);
    for(i = 3; i <= n/2 ; i+=2)
    {
        if(isPrime(i))
        {
            if((isPrime(n-i)))
            {
                count++;
            }
        }
    }


    if(isPrime(n-2))
    {

    count++;

    }

    printf("%d", count);

    return 0;
}
  • You can further optimize the loop with `i <= sqrt(x)` by hardcoding all the primes from 2 to 997, and squaring the factor instead of calling `sqrt`. More ideas in [this Q&A](https://stackoverflow.com/questions/3918968). And, don't forget to upvote and choose your favorite answer :) – Potatoswatter Dec 28 '20 at 19:41
1

I modified your code to optimize it, I have set two Boolean vectors one for 5 mod(6) prime numbers (vet1[i]=false corresponds to prime number 6 x i-1 es. i=1 corresponds to prime number 5=6 x 1-1) and one (vet2[i]corresponds to prime number 6 x i+1) for prime numbers 1 mod(6)

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdbool.h>
void seleciona_primos (bool *vet1, bool *vet2,int n){
    int i, i1,imax;   
    imax=(n-n%6)/6+1;
    for (i=1; (6*i-1)*(6*i-1) <=n; i++){
        if (vet1[i]==false){
            for(int i1 = 6*i*i; i1 <= imax+2*i; i1 += (6*i-1)){
                if(i1<imax)
                   vet1[i1]=true;
                vet2[i1-2*i]=true;        
             }
        }
        if (vet2[i]==false){
            for(int i1 = 6*i*i; i1 <= imax; i1 += (6*i+1)){
                vet1[i1]=true;
                if(i1<imax-2*i)
                    vet2[i1+2*i]=true;        
             }
        }
    }
}

int conta_pares (bool *vet1, bool *vet2, int n){
    int i,imax, count=0,r6;
    imax=(n-n%6)/6;
    r6=n%6;
    if (r6==0){
        for (i=1; i<imax; i++){
                if(vet1[i]== false && vet2[imax-i]== false)
                    count++;
         }
    }
    if (r6==2){
            for (i=1; i<imax; i++){
              if(vet2[i]== false && vet2[imax-i]== false)
                 count++;
            }
            count=(count+count%2)/2;
    }
    if (r6==4){
        for (i=1; i<=imax; i++){
          if(vet1[i]== false && vet1[imax+1-i]== false)
                 count++;
        }
        count=(count+count%2)/2;
    }
    if (r6>0 && r6<3){
        if (vet1[imax]==false)
        count++;  
    }
    if (r6>2 && r6<5){
        if (vet2[imax]==false)
    count++;   
    }
    return count;
}

int main()
{
    int  n, i , count;
    bool *vet1, *vet2;
    scanf("%d", &n);

    vet1 = (bool *) calloc((n-n%6)/6+2, sizeof(bool));
    vet2 = (bool *) calloc((n-n%6)/6+2, sizeof(bool));


    seleciona_primos(vet1,vet2, n);

    count = conta_pares(vet1,vet2, n);

    printf("%d",count);
    free(vet1);
    free(vet2);
   return 0;
}
user140242
  • 159
  • 6