Reputation: 1
I have to write code that finds prime factors. Also, I have to keep in mind the factors that appear multiple times. For 12, I know how to write the code that returns 3 and 2.
def prime_factors(n):
for possible_prime in range(2,int(math.sqrt(n)+1)):
redundant=n%possible_prime
if redundant==0:
for last_check in range(2,int(math.sqrt(possible_prime)+1)):
redundant2=possible_prime%last_check
if redundant2!=0:
print(possible_prime)
But what I need to get is 2, 2, 3. Can anyone help? I am supposed to use loops and lists.
Thanks in advance.
Shai
Upvotes: 0
Views: 367
Reputation: 89507
Here is an example of how to find prime factors using recursion and walrus operator
def prime_factors(n):
for i in range(2, int(n ** 0.5) + 1):
if (q_r := divmod(n, i))[1] == 0:
return [i] + factor_list(q_r[0])
return [n]
>>> prime_factors(12)
[2, 2, 3]
Upvotes: 0
Reputation: 102
It is often better to keep things simple and stupid (KISS principle). Although there are more efficient algorithms to do prime factorization, this one is straight forward:
import math
def prime_factors(n):
res = []
# handle factors 2 first
while n%2 == 0:
res.append(2)
n = n//2
fac = 3
# handle all odd factors until limit reached
while fac < int(math.sqrt(n))+1:
while n%fac == 0:
res.append(fac)
n = n//fac
fac += 2
# append remaining prime factor
if n > 2:
res.append(n)
return res
print (prime_factors(2222222222))
Note use of //
for integer division in Python 3.
Upvotes: 1
Reputation: 23
I am new to Python but will give it a try (please correct me if the synthax is not perfect)
def prime_factors(n):
prime_list = []
job_done = False
first_prime = 2
while not job_done:
for possible_prime in range(first_prime,n+1):
if n%possible_prime == 0:
prime_list.append(possible_prime)
first_prime = possible_prime
n = int(n/possible_prime)
if n == 1:
job_done = True
break
return prime_list
Upvotes: 0
Reputation: 5286
First of all you should remove all even numbers from the range()
to optimize the loop, I would also suggest adding one to the integer form of the sqrt to keep types consistent.
The second loop is not optimized either, as every time the first loop results in a redundant == 0
the possible prime is either prime or a combination of already found primer factors, thus reducing the amount of numbers you need to check against
def prime_factors(n):
factors = []
for possible_prime in [2] + range(3, int(math.sqrt(n))+1, 2):
if not (n % possible_prime):
limit = int(math.sqrt(possible_prime)
is_prime = True
for factor in factors:
if factor > limit:
break
if not (possible_prime % factor):
is_prime = False
break
if is_prime:
factors.append(possible_prime)
return factors
As you said, this gives you all prime factors, now we just want to duplicate (or further) if apropiate:
def prime_factors(n):
factors = []
for possible_prime in [2] + range(3, int(math.sqrt(n))+1, 2):
if not (n % possible_prime):
limit = int(math.sqrt(possible_prime)
is_prime = True
for factor in factors:
if factor > limit:
break
if not (possible_prime % factor):
is_prime = False
break
if is_prime:
factors.append(possible_prime)
factors_copy = factors[:]
for factor in factors_copy:
i = 0
j = n
while not(j % factor):
i += 1
j /= factor
for k in range(i-1):
factors.append(factor)
return sorted(factors)
Upvotes: 0