0

I've been asked to factorize a number and show it in a specific way .

e.g: 100 = 2^2*5^2

This is the C++ code I've used so far with no dice , unfortunately:

#include <stdio.h>
#include <math.h> 

//IsPrime indicates whether a given number is or is not prime.
bool IsPrime(long long n)
{   
    int j = 3;
    if (n == 2)
    {
        return true;
    }
    else if (n % 2 == 0)
    {
        return false;
    }
    else
    {
        for (j = 3; j <= sqrt(n); j += 2)
        {
            if (n%j == 0)
            {
                return false;
            }
        }
    }
    return true;
}

int main(void)
{
    long long n_orig,n, i=3 , primecount=0;
    scanf("%lld", &n_orig);
    n = n_orig;
    if (n == 1)
    {
        printf("1");
        return 0;
    }
    if (IsPrime(n))
    {
        printf("%lld", n);
        return 0;
    }
    if (n % 2 == 0)
    {
        while (n >= 2 && n % 2 == 0)
        {
            primecount++;
            n = n / 2;
        }
        if (primecount == 1)
        {
            printf("2*");
        }
        else
        {
            printf("2^%lld*", primecount);
        }
    }
    primecount = 0;
    n = n_orig;
    while (i <= n/2)
    {
        if (IsPrime(i))
        {
            while (n >= i && n % i == 0)
            {
                primecount++;
                n = n / i;
            }
        }
        n = n_orig;
        if (primecount == 0)
        {
            i++;
            continue;
        }
        if (primecount == 1)
        {
            printf("%lld*", i);
        }
        else
        {
            printf("%lld^%lld*", i, primecount);
        }
        primecount = 0;
        i+=2;
    }
    printf("\b");
    return 0;
}

Using this code I was able to generate a few test cases, though when I uploaded my answer to the website where the codes are presumably evaluated , out of 7 test cases (which I cannot know what they exactly are) , I pass 3 , fail 3 and exceed time limit (the one that hasn't even been declared in the question) in one case. I'd really appreciate some help , and please be noob-friendly!

Also , I don't really wanna know if my answer could be improved in some way , my top priority right now is understanding why MY own code doesn't work as intended.

P.S : Usage of iostream and arrays is not allowed.

Thanks in advance.

Slava
  • 42,063
  • 1
  • 43
  • 86

3 Answers3

1

Try this:

#include <stdio.h>
#include <math.h>

unsigned long long PrintMultiplicity(unsigned long long n,unsigned long long factor)
{
    unsigned int count = 0;

    while (n%factor == 0)
    {
        count++;
        n /= factor;
    }

    if (count > 0)
    {
        printf("%llu^%u",factor,count);
        if (n > 1)
            printf("*");
    }

    return n;
}

void PrintFactorization(unsigned long long n)
{
    unsigned long long factor;
    unsigned int add;

    printf("%llu = ",n);

    n = PrintMultiplicity(n,2);
    n = PrintMultiplicity(n,3);

    // Check only factors that are adjacent to multiples of 6
    for (factor = 5, add = 2; factor <= sqrt(n); factor += add, add = 6-add)
        n = PrintMultiplicity(n,factor);

    if (n > 1)
        printf("%llu^1",n);

    printf("\n");
}

int main()
{
    unsigned long long n;
    scanf("%llu",&n);
    PrintFactorization(n);
    return 0;
}
barak manos
  • 28,602
  • 9
  • 56
  • 111
  • Thanks! This one seems to be working. Two questions though , would you please explain how PrintFactorization works, and also I would like to know what seems to be wrong with my program , as mine and yours seem to be working alike, at least for a few test cases. – FuriousMathematician Nov 02 '16 at 16:56
  • @FuriousMathematician: I added a note above the line which you might find difficult to understand. – barak manos Nov 03 '16 at 07:08
  • I guess `add = 4-add` should actually be `add = 6-add`. – Henry Nov 03 '16 at 07:27
  • @Henry: Yes, good catch! Will speed things up a bit. Thanks for pointing that out!!! – barak manos Nov 03 '16 at 07:35
  • @barakmanos uhh , I'm kinda sure I'm starting to look like an idiot but I still can't quite figure out the algorithm you're using. What does "factors that are adjacent to 6" have to with anything? – FuriousMathematician Nov 03 '16 at 12:16
  • @FuriousMathematician: [5,7],[11,13],[17,19],[23,25],... All the numbers that are not divisible neither by 2 nor by 3. There is no point in checking all the rest, since that are obviously not prime. This reduces the number of tested factors by a magnitude of 3 (i.e., we are left with only one third of the original amount of factors to be tested). – barak manos Nov 03 '16 at 12:22
  • @FuriousMathematician: Please note that I've fixed `add = 4-add` to `add = 6-add`, thanks to Henry's comment (in case you're using this code anywhere)... – barak manos Nov 04 '16 at 16:08
0

You need to perform some fine optimisations. Do not invoke isPrime() method for each value, instead consider a different approach so that irrelevant values can be ignored altogether at the very beginning.

  1. Get the list of relevant primes numbers that comes under n, using Sieve of Eratosthenes concepts.
  2. Start from the lowest prime value from the list, divide n to get intermediate values as

    n / lowest_prime_that_perfectly_divide_n.

    Continue doing this by checking with next higher prime value till n becomes 1. This way you would have count of each dividing factors.

Community
  • 1
  • 1
Saurav Sahu
  • 11,445
  • 5
  • 53
  • 73
0

You do not need prime tests, and lists of primes or prime wheels are only needed for acceleration. A simple program listing all prime factors is

#include <stdio.h>
#include <math.h> 

int main(void)
{
    long long n_orig,n,k;
    scanf("%lld", &n_orig);
    n = n_orig;
    k=2;
    while(k*k<=n) {
        while(0==n%k) {
            n = n/k;
            printf("%lld ",k);
        }
        k++;
    }
    if(n>1) printf("%lld ",n);
    printf("\n");
    return 0;
}

This does not generate the required output format, but that can easily added to it.

Lutz Lehmann
  • 23,321
  • 2
  • 19
  • 49