import random from mod_inverse import modinv def test_basic(): assert modinv(3, 11) == 4 assert modinv(10, 17) == 12 assert modinv(1, 5) == 1 def test_none(): assert modinv(2, 4) is None assert modinv(6, 9) is None assert modinv(0, 5) is None def test_negative_a(): assert modinv(-1, 7) == 6 assert ( (-1)*modinv(-1,7) ) % 7 == 1 % 7 def test_brute(): for m in range(2, 200): for a in range(0, m): x = modinv(a, m) g = None # compute gcd import math if math.gcd(a % m, m) != 1: assert x is None, (a, m, x) else: assert x is not None and 0 <= x < m assert (a * x) % m == 1 def test_random_large(): random.seed(1) for _ in range(2000): m = random.randint(2, 10**6) a = random.randint(0, m-1) x = modinv(a, m) import math if math.gcd(a, m) != 1: assert x is None else: assert x is not None and (a*x)%m == 1 if __name__ == "__main__": test_basic(); test_none(); test_negative_a(); test_brute(); test_random_large() print("ALL PASS")