Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

📚 The CoCalc Library - books, templates and other resources

132930 views
License: OTHER
1
#!/usr/bin/env python
2
# -*- coding: utf-8 -*-
3
4
5
def extended_euclidean_algorithm(a, b):
6
"""
7
Calculates gcd(a,b) and a linear combination such that
8
gcd(a,b) = a*x + b*y
9
10
As a side effect:
11
If gcd(a,b) = 1 = a*x + b*y
12
Then x is multiplicative inverse of a modulo b.
13
"""
14
aO, bO = a, b
15
16
x = lasty = 0
17
y = lastx = 1
18
while (b != 0):
19
q = a/b
20
a, b = b, a % b
21
x, lastx = lastx-q*x, x
22
y, lasty = lasty-q*y, y
23
24
return {
25
"x": lastx,
26
"y": lasty,
27
"gcd": aO * lastx + bO * lasty
28
}
29
30
31
def solve_linear_congruence_equations(rests, modulos):
32
"""
33
Solve a system of linear congruences.
34
35
Examples
36
--------
37
>>> solve_linear_congruence_equations([4, 12, 14], [19, 37, 43])
38
{'congruence class': 22804, 'modulo': 30229}
39
"""
40
assert len(rests) == len(modulos)
41
x = 0
42
M = reduce(lambda x, y: x*y, modulos)
43
44
for mi, resti in zip(modulos, rests):
45
Mi = M / mi
46
s = extended_euclidean_algorithm(Mi, mi)["x"]
47
e = s * Mi
48
x += resti * e
49
return {"congruence class": ((x % M) + M) % M, "modulo": M}
50
51
if __name__ == "__main__":
52
import doctest
53
doctest.testmod()
54
55