Search code examples
pythonprime-factoringexponent

How to calculate the exponents of prime factors for a given number?


I just completed the 3rd project Euler question which asks you to find the largest prime factor of a given number. I made a function which returns a list of all the prime factors for a number.

For example, if you input 100 it would return [2.0, 5.0]

I want to try and now make a program which returns a list with the prime factors appearing the same number of times as their exponent.

So for example, inputting 100 would instead return [2.0, 2.0, 5.0, 5.0] (because 100 is 2^2 * 5*2).

I have written a function which does this correctly if a list containing the prime factors and a list containing the exponents are put in. The problem is that the function I have used to get the list of exponents is wrong.

The code I have written fails for certain numbers (18, 36, 50, 54...).

I am fairly new to programming so if anybody could help me out I would really appreciate it.

def p_fctr_exp(n):
    """Prime factorises n and gives the exponents of each factor"""
    l1 = prime_factors(n) #Initialisation of variables and lists ('prime_factors() ) is just the function I made which gives a list of the prime factors
    p = 1
    exp=[]
    result=[]
    for x in l1:    #This multiplies the prime factors together just once
        x = float(x)
        p = (p * x)
    for x in range(0,len(l1)):  
        """Loop which cycles through factors from smallest first and multiplies 
    the total by the factor until the point where one more would make it bigger
    than the target number. The number of cycles required is stored in the 
    list 'exp'""" 
        a=1
        while p<n:
            p = p*float(l1[x])
            a+=1
        if p == n:
            exp.append(a)
        elif x < len(l1)-1:
            exp.append(a-1)
    return exp

I think the problem occurs in the while loop since it works by multiplying the product p by the lowest prime factor until that becomes too big and then moving up to the next prime factor. The problem is if say the correct exponent should be 2, but increasing it to 3 doesn't make the product bigger than the target number.

I have a feeling this is probably just completely the wrong way of solving the problem but I'm stuck on what to change.


Solution

  • You should use the modulo operator %. Say you have a number 270. So, you divide 270 by 3 until it is "stripped" off 3's, ie. has no factors of 3 left.

    • 270/3=90
    • 90/3=30
    • 30/3=10
    • 10 is not divisible by 3.

    So, 270=10 * 33

    Using you prime factors function:

    def p_fctr_exp(n):
        primes = prime_factors(n)
        exp=[]
    
        for p in primes:
            e=0
                while (n%p==0):
                n=n//p       # since p still divides n,
                e+=1         # we divide n by p and increase the exponent
            exp.append(e)
        return exp
    

    Notes

    1. DO NOT use floats for number theory problems. First, modulo operator doesn't work on them. Second, You never know when you are victim of inaccurate precision. Example: 0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1==1.0 evaluates to False. If you need to check divisibility use %.

    2. You are right on the reason your code fails. For 18, prime_factors(18)=[2,3]. since 24 < 18 < 25. Your function reports that the power of 2 in 18 is 4 which is wrong.