This is another post in the Project Euler series, about Problem 3: Largest prime factor where we shall find the largest prime factor in a large number.
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143?
First we need a generator for prime numbers. It is written quite simply. We go through the numbers and check all prime numbers found so far as factors. If we find a divisor, this number is not a prime number and we go to the next number. If we could go through all known prime factors and did not find a divisor, the new number is a prime number.
def prime_generator() -> int:
primes = []
for candidate in itertools.count(2):
for prime in primes:
if candidate % prime == 0:
break
else:
yield candidate
primes.append(candidate)
Now we can write a naive implementation for the number 13195. We just iterate through all primes up to that number and then remember the biggest prime factor that we have found.
number = 13195
def solution_naive() -> int:
factor = None
for prime in prime_generator():
if number % prime == 0:
factor = prime
if prime > number:
break
return factor
Running this gives us the result 29, which we know from the problem statement. It took 49 ms to compute that.
Trying to run this with the actual number of 600,851,475,143, we have a problem. It doesn’t find a solution within a few seconds, so clearly this is not the intended solution.
A better way is to divide out the prime factors as we find them. This will reduce the problem size as we go. This is a slightly changed solution where we always reduce the remainder until the given prime is no longer a divisor.
def solution_reducing() -> int:
remainder = number
last_factor = None
for prime in prime_generator():
while remainder % prime == 0:
last_factor = prime
remainder /= prime
if remainder == 1:
break
return last_factor
With the small number it only takes 5 µs, so it is a factor 10,000 faster than the naive version. And with the actual number we get a result of 6,857 in just 16 ms, which seems fast enough.