-1

I have to find multiplicity of smallest prime factor in all numbers till 10^7.I am using Sieve of Eratosthenes to find all the prime numbers. And there in a seperate array phi i am storing smallest prime factors of composite numbers.Here is my code for that

 for(ull i=2;i<=m;i++)
{
    if (check[i])
    {
         uncheck[i]=true;
        for (ull k=i*i; k<=n; k+=i)
         {
           if(check[k]==true)
           phi[k]=g;
           check[k]=false;
         }  
    }

}

Now i am running a loop till n and using a loop inside it to calculate it. Here is code for that

 for(ull i=4;i<=n;i++)
{

    if(check[i]==false)
    {   
        ull count=0; 
        ull l=i;
         ull r=phi[i];
         while(l%r==0)
         {
            l=l/r;
            count++;
         }               
        cout<<count<<'\n';
    }


}

Is there any faster way to compute this?

5 Answers5

5

Absolutely, you can do this without a loop.

c is probably at most 64 bits. It cannot contain any factor other than 1 more than 63 times. So instead of a loop, you write 63 nested if-statements.

For the case j == 2 your compiler may have some intrinsic functions that count trailing zero bits. If that is the case, then you handle that case separately and you need only 40 if's, because 3^41 > 2^64.

gnasher729
  • 51,477
  • 5
  • 75
  • 98
  • 3
    well... he didn't ask if there is a **better** way so this actually answers the questions. So the moral here is *Be careful what you ask for. You might get it* – bolov Nov 12 '15 at 10:51
2

If you want to evaluate n such that jn = c, then recast the problem to

n = log(c) / log(j).

If n is an integer then your problem is solved.

Of course you need to consider floating point precision here; n might not be an exact integer, but close to one.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • I think this is wrong. It says "j is *one* of its factors". Consider c=62 and j =2. Output should be 1 I guess because j appears exactly one in the factorization of c.... or maybe I understood something wrong.. – dingalapadum Nov 12 '15 at 10:54
  • 1
    I do predicate my answer with the "if" at the top. Sometimes folk just don't know what they want! – Bathsheba Nov 12 '15 at 10:54
  • not sure if this is safe, because `n` might also be close to an integer if j isnt a factor. However, OP also starts from knowing that it is a factor. And I just realized that `j^n=c` should be `j^n * x = c` with x integer. – 463035818_is_not_an_ai Nov 12 '15 at 10:55
  • 1
    He wants to know the multiplicity of `j` in a factorization of `c` I think...I'm inferring that from how he is asking, and because he is complaining about performance of his code... not the result... – dingalapadum Nov 12 '15 at 10:56
  • well i have a set of numbers till 10^7 and i have to find find multiplicity of smallest prime factor in factorization of all the numbers. while loop is slowing it down. That is why i am asking for a better performacewise way? – Vaibhav Vasant Nov 12 '15 at 11:03
  • again please consider adding all such extra info to your original question. people can give better answers when they know exactly what you need, what you've already tried, and where the shortcomings are. – underscore_d Nov 12 '15 at 11:07
0

One alternative option, though not necessarily the most efficient, is to write a simple recursive function, such as this, assuming you are dealing with ints:

int recurseSubtract(int c, int j, int count){
  if ((c==j)) {
    return count + 1;
  } else {
     c = c-j;
     subtract(c, j, count++);
  }
}

int count = recurseSubtract(c,j,0);

However, see here for the pros and cons of loops vs. recursion.

Community
  • 1
  • 1
EkcenierK
  • 1,429
  • 1
  • 19
  • 34
0

Since you asked for the "multiplicity of smallest prime factor" you could easily use the same sieve approach to get multiplicity as you used to get the smallest factor.

 for(ull i=2;i<=m;i++)
{
    if (check[i])
    {
        uncheck[i]=true;  // WHY??
        ull k=i*i;
        for (ull q=i; q<maxq; k=(q*=i))
        for ( ; k<=n; k+=q)
         {
           if(check[k]==true)
               phi[k]=g;  // I copied 'g' from you, but didn't you mean 'i'?
           if ( phi[k]==g )
               count[k]++;
           check[k]=false;
         }  
    }

}

If you want to do a little better than that, the step of phi[k]==g and the some of the redundancy in check[k] access are needed only because q values are processed in forward sequence. It would be faster to work with q in reverse. Since q's are only easily computed in forward sequence and there are fairly few q's per i, the easiest way to process q backward would be to convert the loop over q into a recursive function (compute q on the way in and process it after the recursive call).

JSF
  • 5,281
  • 1
  • 13
  • 20
0

I found one simple rule but can not really describe in words. Here is another code calculating primenumbers

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
double f_power(double val, int exp);
int main(int argc,char* argv[]) {

    int p[2];
    int ctr = 0;
    int ctr2 = 0;
    int it_m = 0;
    int it_1 = 0;
    int it_2 = 0;
    int it_c = 0;


    int index = 3;
    srand(time(NULL));
    double t = clock();
    double s = clock();
    int prime = 2;
    FILE *file;
    file = fopen("ly_prime.txt", "w");
    //f_power(2.0, 57885161)
    for (it_m = 2; it_m <= 2000; it_m++) {
        for (it_1 = it_m, ctr2 = 0, it_c = it_m; it_1 >= 2; it_1--) {
            for (it_2 = it_1; it_2 >= 2; it_2--) {
                if (it_1 * it_2 - it_c == 0) {
                p[ctr % 2] = it_c;
                if (ctr >= 1 && p[ctr % 2] - p[(ctr - 1) % 2] == 2) {
                    //prime[0] = (p[ctr % 2] - 1);
                    prime = (p[ctr % 2] - 1);
                    fprintf(stdout, "|%d _ i: %d _ %d\n", isPrime(prime),index, prime);
                    index++; 
                }
                ctr++;
                }
            }
        }
    }
    t = clock() - t;
    fprintf(file, "|%d_ %d_ %d ", prime, index - 2, ctr);

}
double f_power(double val, int exp) {
int i = 0;
double help = val;
for(i = 1; i < exp; i++) {
    val *= help;
}
return val;
}
int isPrime(int number)
{
        int i = 2;
    for(i=2; i < number; i++)
    {
            int leftOver=(number % i);

            if (leftOver==0)
            {
                    return 1;
                    break;
            }

    }
            return 0;
}

perhaps it helps understanding, best regards

geonb
  • 21
  • 7