简体   繁体   中英

Why doesn't my answer to project euler 3 work?

I've been trying to solve project Euler problem #3 for a while now. The code below still doesn't work the way I want it to.

Question 3: The prime factors of 13195 are 5, 7, 13 and 29.

What is the largest prime factor of the number 600851475143 ?

 getal = 13195
    x = 2 

    while x in xrange(2,getal):
        if getal % x == 0:
            num = getal / x
            for i in xrange (2,num):
                    if num % i == 0:
                        x += 1
                        break
                    else:
                        print num
        else:
            x += 1
            continue

As you can see I'm running it right now with 13195 for the sake of simplicity, but eventually it should have to work with the bigger number.

My output is this:

2639 2639 2639 2639 2639 1885 1885 1885 1015 1015 1015 455 455 455 377
377 377 377 377 377 377 377 377 377 377 203 203 203 203 203 145 145
145 91 91 91 91 91 65 65 65 35 35 35 29 29 29 29 29 29 29 29 29 29 29
29 29 29 29 29 29 29 29 29 29 29 29 29 29

29 goes on for a while longer than I showed. I do understand it just prints the number as soon as it has found an "i" that this number cannot be divided by. But I don't know how to prevent it from doing this. Because in the end 29 is the right answer, however it should just give this answer once and right away.

You can simplify your code to the code snippet below. It uses a list to store any candidates and then removes them if they are not prime numbers:

import math

getal = 600851475143
x = 2 
candidates = [];
while (x < int(math.sqrt(getal)+1)):    
    if getal % x == 0:                
        candidates.append(x)
        for i in xrange (2,int(math.sqrt(x)+1)):
             if x % i == 0:
                 candidates.remove(x)
                 break        
    x = x + 1
print str(candidates).strip('[]')        

您需要break你的的while当你找到答案。

You are not incrementing 'x' after print num statement.

  for i in xrange (2,num):
      if num % i == 0:
         break
      else:
         print num
  x += 1

you should be able to even getrid of second if statement as below

getal = 13195
x = 2 
while x in xrange(2,getal):
  if getal % x == 0:
      num = getal / x
      for i in xrange (2,num):
          if num % i == 0:
             break
          else:
             print num
  x += 1

The Answer is 6857. You don't have to check from 2 to the number. Use the property of primes.Check only up-to the square root of the number that you are checking.You can use my Java Code for reference.

class p3{
public static boolean isprime(long y){
    double sq = Math.sqrt(y);
    long endl =(long) (sq+.5);
    for(long j = 2;j <=endl ;j++)
    {
        if(y%j==0){
        return false;
        }
    }
    return true;
}

public static void main(String []asd){
    long test = 600851475143L;
    long ans =-1;
    double e = Math.sqrt(test);
    long end = (long)(e+1);
    for(long i = 2 ; i <= end ;i++)
    {

        if(test%i==0){
            boolean val = isprime(i);
            if(val){
            ans = i;
            }
        }
    }
    System.out.println(ans);
}
}

If you need any help. I have solved the problems in Project Euler and have saved them in my github repository. You are more than welcome to fork it.The url is: https://github.com/vatsarahul999/ProjectEuler-.git

Writing the same code in python.

 def isprime(n):
   if n < 2:
     return False
  if n == 2: 
    return True    

  if not n & 1: 
    return False

   for x in range(3, int(n**0.5)+1, 2):
      if n % x == 0:
        return False
   return True

Now the main program

v = 13195
x = 2
while(x*x <= v)
  if(isprime(x)):
       a = x
       while(v%x==0)
           v=v/x;
  x++
  print a

Here's a sample (it can be improved in terms of performance):

import math

getal = 600851475143

def prime(number):
    for i in xrange(2, int(math.sqrt(number)) + 1):
        if (number % i) == 0:
            return False
    return True

def prime_factors(number):
    ret = []
    n = number
    primes = []
    for i in [item for item in xrange(2, int(math.sqrt(n)) + 1)]:
        if prime(i):
            primes.append(i)
    for i in primes:
        while n % i == 0:
            ret.append(i)
            n = n / i
    return ret

print prime_factors(getal)

Why is everyone incrementing to find the largest number? Decrease!!!

def largestPrime(num):
  from __future__ import division
  for i in xrange(num//2 + 1, 1, -1):
    if num%i == 0 and all([i%j != 0 for j in range(2,i//2 + 1)]):
      return i

you are over complicating, to get all factors

getal = 13195
for x in range(2, getal):
    if getal % x == 0:
        print x

this one should use the for loop not a while, to use a while here it would be like this

getal = 13195
x = 2
while x < getal:
    if getal % x == 0:
        print x
    x += 1

you dont need to loop thru the constraints to do the work at the loop level - because you are doing it inside

you are actually very close to getting the right answer, you just need to remove indentation in your else statement to have a for else block:

>>> x = 2
>>> getal = 13195
>>> while x in range(2,getal):
        if getal % x == 0:
            num = getal // x
            for i in range (2,num):
                    if num % i == 0:
                        x += 1
                        break #this will break for loop
            else:#this is the only change, moving the else from an else inside of the for to a for else block
                    print (num)
                    break this will break while loop
        else: 
            x += 1
            continue


29

this is surprising for most people because the for-else statement is not well know but it pretty much means to only run the else block if the for block is not exited with a break.

With this in mind, YES, this code works but as a lot of other people said, this is NOT the best way to accomplish this task. Because @RahulVasta posted a good enough answer already, i wont. It is not to say that your logic does not work, but, since this is programming, there are infinite ways to approach a problem and some are better than others.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM