86 lines
1.9 KiB
Python
86 lines
1.9 KiB
Python
"""Tests for factor.py"""
|
|
import random
|
|
from factor import is_prime, factor, totient
|
|
|
|
|
|
def _trial_prime(n):
|
|
if n < 2:
|
|
return False
|
|
if n < 4:
|
|
return True
|
|
if n % 2 == 0:
|
|
return False
|
|
i = 3
|
|
while i * i <= n:
|
|
if n % i == 0:
|
|
return False
|
|
i += 2
|
|
return True
|
|
|
|
|
|
def test_small_primes():
|
|
for n in range(2, 3000):
|
|
assert is_prime(n) == _trial_prime(n), n
|
|
|
|
|
|
def test_carmichaels():
|
|
for c in [561, 1105, 1729, 2465, 2821, 6601, 8911, 10585, 15841, 29341, 41041, 46657, 52633, 62745, 63973]:
|
|
assert not is_prime(c), c
|
|
|
|
|
|
def test_large_known_primes():
|
|
for p in [2**31 - 1, 2**61 - 1, 999999999999999989, 32416190071]:
|
|
assert is_prime(p), p
|
|
|
|
|
|
def test_factor_small():
|
|
for n in range(2, 1000):
|
|
fs = factor(n)
|
|
prod = 1
|
|
for f in fs:
|
|
prod *= f
|
|
assert is_prime(f)
|
|
assert prod == n
|
|
assert fs == sorted(fs)
|
|
|
|
|
|
def test_factor_random_large():
|
|
random.seed(42)
|
|
for _ in range(300):
|
|
def rnd_prime(lo, hi):
|
|
while True:
|
|
x = random.randrange(lo, hi)
|
|
if is_prime(x):
|
|
return x
|
|
a = rnd_prime(1000, 100000)
|
|
b = rnd_prime(1000, 100000)
|
|
n = a * b
|
|
fs = factor(n)
|
|
assert sorted(fs) == sorted([a, b]), (n, fs)
|
|
|
|
|
|
def test_factor_powers():
|
|
for base in [2, 3, 5, 7, 11]:
|
|
for e in [1, 2, 3, 5, 8, 12]:
|
|
n = base ** e
|
|
fs = factor(n)
|
|
assert fs == [base] * e
|
|
|
|
|
|
def test_totient():
|
|
assert totient(1) == 1
|
|
assert totient(2) == 1
|
|
assert totient(10) == 4
|
|
assert totient(12) == 4
|
|
assert totient(30) == 8
|
|
|
|
|
|
def test_edge():
|
|
assert factor(0) == []
|
|
assert factor(1) == []
|
|
assert factor(-12) == [2, 2, 3]
|
|
assert is_prime(0) is False
|
|
assert is_prime(1) is False
|
|
assert is_prime(2) is True
|
|
assert is_prime(999999999999999937 * 2) is False
|