project-euler/lib.py

69 lines
1.4 KiB
Python

#!/usr/bin/env python3
from random import randint
from collections import Counter
FACTOR_SIEVE = []
def primegen(n):
sieve = [False] * n
yield 2
for p in range(3, n, 2):
if sieve[p]:
continue
for i in range(p**2, n, 2*p):
sieve[i] = True
yield p
def iter_factors(n):
sieve = init_factors(n)
for i in range(n):
yield pfactors(i, sieve)
def init_factors(n):
sieve = [False] * n
for p in range(3, n, 2):
if sieve[p]:
continue
for i in range(p**2, n, 2*p):
sieve[i] = p
return sieve
def pfactors(n, sieve=FACTOR_SIEVE):
if n < 1:
if not n:
return Counter()
n = abs(n)
fctrs = Counter()
while not n % 2:
fctrs[2] += 1
n //= 2
while sieve[n]:
fctrs[sieve[n]] += 1
n //= sieve[n]
if n != 1:
fctrs[n] += 1
return fctrs
def miller_rabin(n, k=10):
if not (n % 2 and n % 3):
return False
d = n - 1
r = 0
while not r % 2:
d //= 2
r += 1
for i in range(k):
a = randint(2, n-2)
x = pow(a, d, n)
if x == 1 or x == n - 1:
continue
for j in range(r-1):
x = pow(x, 2, n)
if x == n - 1:
break
else:
return False
return True