Reputation: 22307
I have a code to calculate highest prime factor of 600851475143
.
def PRIME(a): #Check if no is prime
f = 0
i = 2
while(i < a/2): #No factor of a no can be greater than a/2
if (a % i == 0):
f = 1
break
i = i + 1
if(f == 1):
return 0
else:
return 1
def PFIND(a):
for i in range(1, 100000): #Iteratively check if the no is prime
if PRIME(a/2 - i): #No factor of a no can be greater than a/2.
if (a % (a/2 - i) == 0):
return (a/2 - i)
print PFIND(600851475143)
But the code runs on and on and on and does'nt give any output.
Upvotes: 1
Views: 462
Reputation: 123393
Python's long number support is very verbose and well tested, so I doubt that's the problem. One thing I noticed about your code is that it hasn't be optimized at all and computes the value a/2
several times during in each iteration of the loop. However even if you fixed that it would likely still be too slow because finding prime factors can be a very time consuming especially for larger numbers.
For that reason I think the best approach would be to find a better algorithm. Here's code derived from one I found which calculates all the prime factors of a number. I converted it to Python and simplified it to just keep track of the largest factor it finds. It quickly returned the correct answer for your test case, whose prime factors are {71, 839, 1471, & 6857}.
def maxprimefactor(n):
""" find the largest prime factor of a positive integer """
maxfactor = None
divisor = 2
while divisor*divisor <= n:
if n % divisor:
divisor += 1
else:
maxfactor = divisor
n /= divisor
if n != 1:
maxfactor = n
return maxfactor if maxfactor else 1
print maxprimefactor(600851475143)
# 6857
Upvotes: 0
Reputation: 113905
I wrote some hobby code that has to do with prime numbers in the past, which I've adapted to work for your purposes. Here is the code:
def isPrime(n, primes=[]):
""" Return True iff n is a prime number.
If primes is non-empty, return true iff n is co-prime to every number in primes. """
if not len(primes):
if n <= 2:
return True
elif n%2 == 0:
return False
else:
prime = True
for i in range(3, n, 2):
if n%i == 0:
prime = False
if prime:
return True
else:
for p in primes:
if not n%p:
return False
return True
def next(n, primes):
""" Return a number p such that
1. p is co-prime to every number in primes
2. p>n and p-n is as small as possible"""
curr = n+1
while 1:
if isPrime(curr, primes):
return curr
else:
curr += 1
def generate(n):
""" Yield the first n prime numbers"""
primes = [2]
curr = 2
for _ in range(n-1):
p = next(curr, primes)
primes.append(p)
curr = p
yield p
def primeNumbers(n):
""" return a list of prime numbers such that all numbers in the list are at most n
1 is a prime number"""
answer = []
if n <= 2:
answer.append(n)
else:
for i in range(3, n+1, 2):
prime = True
for p in answer:
if i%p == 0:
prime = False
break
if prime:
answer.append(i)
return answer
def PFIND(n):
primes = primeNumbers(n)
primes.reverse()
for p in primes:
if n%p == 0:
return p
That should do it.
Hope this helps
Upvotes: 0
Reputation: 3158
I've found that Python does a great job with large integers. As already mentioned, you are using two brute force tests to crack this nut.
Try this:
a = 600851475143
q = 2
while q <= a / 2:
if not a % q:
a /= q
p = q
else:
q += 1
print p
Upvotes: 0
Reputation: 90985
Your loop condition of
while(i < a/2):
is making your algorithm take O(N) time.
A simple modification will improve this to O(√N).
hi = int(math.sqrt(a) + 1) # +1 in case of rounding error.
while i <= hi:
Upvotes: 0
Reputation: 308091
Rather than starting out with a huge number for testing, try your algorithm on smaller numbers. Then try progressively larger numbers. Plot the amount of time the function takes - I'd suggest using the timeit
module. Then extrapolate and estimate how long the function will take on the number you're trying.
I think you'll find that your algorithm is taking so long that it looks like it never finishes.
Upvotes: 3
Reputation: 5218
Python's support for large integers is fine. I think your problem is that you're doing very slow algorithms for both brute-force finding the factor and testing whether your factor is prime. If you just invert the order of those two tests (ie, test whether it's a factor, then test whether it's prime), it'll go a lot faster.
But perhaps the problem was about using more sophisticated algorithms. Maybe you should use the Rabin-Miller test instead of brute-force.
Upvotes: 8