Project Euler #3, infinite loop on factorization

限于喜欢 提交于 2019-12-12 10:19:53

问题


So I'm doing Project Euler because dear gods do I need to practice writing code, and also my math skills are rusty as something very rusty. Thusly; Project Euler. I'm sure most here have already seen or heard of the problem, but I'll put it here just for completeness:

The prime factors of 13195 are 5, 7, 13 and 29. What is the largest prime factor of the number 600851475143 ?

For this, I've written two functions:

from math import sqrt

def isprime(n):
    if n == 1:
        return False
    elif n == 2:
        return True
    elif n % 2 == 0:
        return False
    for x in range(3, round(sqrt(n))+1, 2):
        if n % x == 0:
            return False
    else:
        return True

This just checks any fed number for primality. It's working as intended (as far as I know), but now that I've said that I grow unsure. Anyway, it checks for special cases first: 1 (never prime), 2 (prime) or if it's divisible by 2 (not prime). If none of the special cases happen, it runs a general primality test.

This is my factorization code:

def factorization(n):
   factor = 2
   x = 3
   while True:
       if n % x == 0:
           if isprime(x):
               factor = x
               n = n // x
               if n == 1:
                   return factor
           else:
               return factor
       x += 2

And this is definitely not working as intended. It is, sadly, working for the particular value of the Project Euler problem, but it doesn't work for, say, 100. I'm unsure what I need to do to fix this: what happens is that if it's a number like 100, it will correctly find the first 5 (2*2*5), but after that will loop around and set x = 7, which will make the entire thing loop infinitely because the answer is 2*2*5*5. Would recursion help here? I tried it, but it didn't get any prettier (it would still go into an endless loop for some numbers). I'm unsure how to solve this now.


回答1:


You're on a good track, but you need to take account of the possibility of repeating factors. You can do that with something like this:

factors = []

while num % 2 == 0:
  factors.append(2)
  num /= 2

The idea here being that you're going to continue adding 2's to the factor list until the number you're testing becomes odd. You can use similar logic for other factors as well to enhance your factorization method.




回答2:


I think you have made the problem more complicated than necessary

Here is some pseudo code that you should be able to turn into Python code

from itertools import count
n=600851475143  
for x in count(2):
    while x divides n:
        divide n by x
    if n==1:
        print x # largest factor will be the last one
        break



回答3:


For the repeating (odd) factors, just increment x when a divisor has not been found:

def factorization(n):
    factor = 2
    x = 3
    while True:
        if n % x == 0:
            if isprime(x):
                factor = x
                n = n // x
                if n == 1:
                    return factor
            else:
                return factor
        else:
            x += 2

OTOS, it seems that you miss always the "2" factors. Stick them on top and then do the main loop

EDIT (after comment)

You can do a much simpler:

def factorization(n):
    factors = []
    x = 2
    while True:
        while n % x == 0:
            factors.push(x)
            n /= x
        if n == 1:
            return factors
        if x == 2:
            x = 3
        else: 
            x += 2



回答4:


Here is another optimized solution:

import math

def find_prime(num):
    if num <= 1:
        return False
    elif(num == 2):
        return True
    elif( num % 2 == 0):
        return False
    for i in range(3, int(math.sqrt(num))+1, 2): 
        if num%i == 0:
            return False 
    return True

def prime_factor(number):
    pf = number;
    divList = [];

    for i in range(2, int(math.sqrt(number))):
        if number % i == 0 :
            divList.append(i)

    for n in divList:
        if(find_prime(n)):
            pf = n;

    return pf

num = 600851475143
print("Max prime factor :", prime_factor(num))


来源:https://stackoverflow.com/questions/8350694/project-euler-3-infinite-loop-on-factorization

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!