def lcm(a, b): """calculates the least common multiple of the given numbers""" factors_a = map_list(factor.factorize(a)) factors_b = map_list(factor.factorize(b)) lcm_factors = {} for k in factors_a.keys(): lcm_factors[k] = factors_a[k] for k in factors_b.keys(): if lcm_factors.get(k) == None: lcm_factors[k] = factors_b[k] elif lcm_factors[k] < factors_b[k]: lcm_factors[k] = factors_b[k] lcm = 1 for k in lcm_factors: lcm *= k**lcm_factors[k] return lcm
def euler(n): if n == 1: return 1 res = 1 for m, n in canonicalize(factorize(n)): res *= m**n - m**(n - 1) return res
def gcd(a, b): """calculates the greatest common divisor of the given numbers""" factors_a = map_list(factor.factorize(a)) factors_b = map_list(factor.factorize(b)) gcd_factors = {} for k in factors_a.keys(): b_factor = factors_b.get(k) if b_factor == None: continue if factors_a[k] < factors_b[k]: gcd_factors[k] = factors_a[k] else: gcd_factors[k] = factors_b[k] gcd = 1 for k in gcd_factors: gcd *= k**gcd_factors[k] return gcd
def is_prime(p): q = max(factorize(p-1)) if p > (q + 1) ** 2: return None for a in islice(a_generator(p), 3): if euclid(a ** ((p - 1) // q) - 1, p)[0] == 1: return True return None
def residue_class(a, k, m): if is_prime(m): p = m - 1 k = k % p x = a**k % m return x, m else: p_arr, n_arr = list(map(list, zip(*canonicalize(factorize(m))))) if any(n > 1 for n in n_arr): return None system = [[a**(k % (p - 1)) % p, p] for p in p_arr] return chiness(system)
def jacobi_symbol(a, n): return reduce(lambda x, y: x * legendre_symbol(a, y), factorize(n), 1)
def primitive_root(m): c = euler(m) for a in range(2, c): if all((a ** (c // p)) % m != 1 for p in factorize(c)): return a
def test_factorize(self): self.assertEqual(sorted([3, 41]), sorted(factorize(123))) self.assertEqual(sorted([2, 2, 3, 73]), sorted(factorize(876))) self.assertEqual([23], factorize(23))