from sympy.core.numbers import igcdex def crt(m, v, symmetric=False): """Chinese Remainder Theorem. The integers in m are assumed to be pairwise coprime. The output is then an integer f, such that f = v_i mod m_i for each pair out of v and m. """ mm = 1 for m_i in m: mm *= m_i result = 0 for m_i, v_i in zip(m, v): e = mm // m_i s, t, g = igcdex(e, m_i) c = v_i*s % m_i result += c*e result %= mm if symmetric: if result <= mm//2: return result else: return result - mm else: return result def crt1(m): """First part of chines remainder theorem, for multiple application. """ mm, e, s = 1, [], [] for m_i in m: mm *= m_i for m_i in m: e.append(mm // m_i) s.append(igcdex(e[-1], m_i)[0]) return mm, e, s def crt2(m, v, mm, e, s, symmetric=False): """Second part of Chinese Remainder Theorem, for multiple application. """ result = 0 for m_i, v_i, e_i, s_i in zip(m, v, e, s): c = v_i*s_i % m_i result += c*e_i result %= mm if symmetric: if result <= mm // 2: return result else: return result - mm else: return result