some-factorization-algorithms/utils.py

72 lines
1.9 KiB
Python

from collections import defaultdict
def is_prime(N):
"""
Тест Миллера-Рабина проверки числа на простоту.
"""
if N < 2:
return False
for p in [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31]:
if N % p == 0: return N == p
d = N - 1
s = 0
while d % 2 == 0:
d >>= 1
s += 1
for a in [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31]:
if a >= N: continue
x = pow(a, d, N)
if x == 1 or x == N - 1: continue
for _ in range(s - 1):
x = pow(x, 2, N)
if x == N - 1: break
else: return False
return True
def primes(B):
"""
Возвращает список всех простых чисел до B.
"""
primes_list = []
is_prime = [True] * (B + 1)
is_prime[0] = is_prime[1] = False
for p in range(2, B + 1):
if is_prime[p]:
primes_list.append(p)
for i in range(p * p, B + 1, p):
is_prime[i] = False
return primes_list
def first_primes(n):
"""
Возвращает список первых n простых чисел.
"""
primes_list = []
candidate = 2
while len(primes_list) < n:
is_prime = True
for p in primes_list:
if p * p > candidate:
break
if candidate % p == 0:
is_prime = False
break
if is_prime:
primes_list.append(candidate)
candidate += 1
return primes_list
def is_smooth(n, base):
"""
Проверяет, является ли число гладким относительно factor_base
"""
if n == 0: return None
fact = [0] * len(base)
for i, p in enumerate(base):
if n == 1: break
while n % p == 0:
n //= p
fact[i] += 1
if n != 1:
return None
return fact