def prob5(): factors = {} for i in range(1,21): prime_factors = utils.prime_factorization(i) utils.dict_merge(factors, prime_factors) product = utils.prime_defactorization(factors) return product
def blum_blum_shub(p, q): assert p % 4 == 3 and q % 4 == 3 n = p * q possible_seeds = prime_factorization(n) seed = random.choice(possible_seeds) seeds = seed_generator(seed, n) for s in seeds: yield s % 2
def encryption_key(p, q): #assert p % 3 == 4 and q % 3 == 4 phi_n = phi(p, q) public_key = random.randint(1, 2 ** 128) phi_factors = prime_factorization(phi_n) while public_key in phi_factors: public_key = random.randint(1, 2 ** 128) return public_key
def prime_factorization(base, power): factorization = utils.prime_factorization(base) for factor in factorization: factorization[factor] *= power factorization_str = '' for factor, power in factorization.items(): factorization_str += '{}^{},'.format(factor, power) return factorization_str
def sum_proper_divisor(n): pf = prime_factorization(n) sum_d = 1 for p in pf: d = 0 for i in range(pf[p] + 1): d += p**i sum_d *= d sum_d -= n return sum_d
def prob3(): prime_factors = utils.prime_factorization(600851475143) return list(prime_factors)[0]
# Highly divisible triangular number from utils import prime_factorization max_divisor = 0 for i in range(2, 15000): p1 = prime_factorization(i) p2 = prime_factorization(i+1) c = p1 + p2 divisor = 1 for count in c.values(): divisor *= (count+1) if divisor > max_divisor: max_divisor = divisor print max_divisor if divisor > 500: print i, i*(i+1)/2, c break
from collections import Counter from functools import reduce from operator import mul import utils high = 100000 utils.initialize_primes_cache(high) # explanation: nth triangle number = n*(n-1)/2 = (n^2 - n)/2 < n^2 # highest prime factor of that can be sqrt # so n is upper bound on highest prime factor of nth triangle number s = 0 for i in range(1, high): s += i pf = Counter(utils.prime_factorization(s)) # explanation: we don't need to know the actual divisors, just how many of them there are # itertools.combinations would let us enumerate the actual divisors num_divisors = reduce(mul, (exp + 1 for (prime, exp) in pf.items()), 1) print(s, num_divisors) if num_divisors > 500: break
def random_near_primitive_root(p): start = random.randint(2, p - 1) primes_to_test = prime_factorization(p - 1) for b in infinite_range(start, p): if primitive_root(b, primes_to_test, p): return b
import sys sys.path.append('../utils') from utils import is_prime, prime_factorization for x in range(10,200000): a = prime_factorization(x) if len(set(a)) == 4: b = prime_factorization(x+1) if len(set(b)) == 4: c = prime_factorization(x+2) if len(set(c)) == 4: d = prime_factorization(x+3) if len(set(d)) == 4: print(str(x) + ': [%s]' % ', '.join(map(str, a))) print(str(x+1) + ': [%s]' % ', '.join(map(str, b))) print(str(x+2) + ': [%s]' % ', '.join(map(str, c))) print(str(x+3) + ': [%s]' % ', '.join(map(str, d))) assert 5 == 6
import utils upper_bound = 200000 num_consec = 4 utils.initialize_primes_cache(upper_bound) factors = dict((i, set(utils.prime_factorization(i))) for i in range(4, upper_bound)) for i in range(4, upper_bound): if all(len(factors[i+j]) >= num_consec for j in range(num_consec)): print(i, factors[i]) break