Skip to content

Instantly share code, notes, and snippets.

@estebistec
Created April 28, 2018 23:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save estebistec/5a847fb4677700c728f9c8d26ca37af6 to your computer and use it in GitHub Desktop.
Save estebistec/5a847fb4677700c728f9c8d26ca37af6 to your computer and use it in GitHub Desktop.
Find prime factorizations of numbers, with small optimizations
import math
def require_int(n):
if not type(n) is int:
raise TypeError('argument must have type int; got {} which has type {}'.format(n, type(n).__name__))
def require_non_negative_int(n):
require_int(n)
if n < 0:
raise ValueError('argument must be an int >= 0; got {}'.format(n))
def is_prime(n):
require_non_negative_int(n)
if n == 0:
return False
return not any(d for d in range(2, math.floor(math.sqrt(n)) + 1) if n % d == 0)
KNOWN_PRIMES_ORDERED_CACHE = []
def primes_under(n):
"Generate a sequence of prime numbers less than n"
require_non_negative_int(n)
for p in KNOWN_PRIMES_ORDERED_CACHE:
if p < n:
yield p
else:
break
continue_at = KNOWN_PRIMES_ORDERED_CACHE[-1] + 1 if KNOWN_PRIMES_ORDERED_CACHE else 2
for d in range(continue_at, n):
if is_prime(d):
KNOWN_PRIMES_ORDERED_CACHE.append(d)
yield d
def prime_factors(n):
"Return a list of prime integers, that multiplied together, result in n"
require_non_negative_int(n)
factor_seek_limit = math.floor(math.sqrt(n)) + 1
current = n
factors = []
while not is_prime(current):
for f in primes_under(factor_seek_limit):
if current % f == 0:
factors.append(f)
current //= f
break
factors.append(current)
return factors
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment