-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathring.py
114 lines (88 loc) · 2.76 KB
/
ring.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import numpy as np
def GCD(a, b):
m = np.array([1, 0])
n = np.array([0, 1])
while b:
p, r = divmod(a, b)
m, n = n, m-p*n
a, b = b, r
return a, m
def divmodr(b, m, n=None):
if n is None:
return divmod(b, m)
k, (c, d) = GCD(m, n)
p, r = divmod(b, k)
return (p*c) % n, r
class RingBase:
_base = 1
_verbose = True
def __init__(self, arg=0):
if isinstance(arg, RingBase):
self.val = arg.val % self._base
else:
self.val = arg % self._base
def __int__(self):
return int(self.val)
def __str__(self):
if self._verbose:
return "{} (mod {})".format(self.val, self._base)
else:
return str(self.val)
def __repr__(self):
return str(self)
def __add__(self, rhs):
rhs = self.__class__(rhs)
return self.__class__(self.val+rhs.val)
def __radd__(self, lhs):
lhs = self.__class__(lhs)
return self.__class__(self.val+lhs.val)
def __sub__(self, rhs):
rhs = self.__class__(rhs)
return self.__class__(self.val-rhs.val)
def __rsub__(self, lhs):
lhs = self.__class__(lhs)
return self.__class__(lhs.val-self.val)
def __mul__(self, rhs):
rhs = self.__class__(rhs)
return self.__class__(self.val*rhs.val)
def __rmul__(self, lhs):
lhs = self.__class__(lhs)
return self.__class__(self.val*lhs.val)
def __truediv__(self, rhs):
rhs = self.__class__(rhs)
p, r = divmodr(self.val, rhs.val, self._base)
if r:
raise ZeroDivisionError("Unsolvable congrunce division")
return self.__class__(p)
def __rtruediv__(self, lhs):
lhs = self.__class__(lhs)
return lhs/self
def __floordiv__(self, rhs):
rhs = self.__class__(rhs)
p, r = divmodr(self.val, rhs.val, self._base)
return self.__class__(p)
def __rfloordiv__(self, lhs):
lhs = self.__class__(lhs)
p, r = divmodr(lhs.val, self.val, self._base)
return self.__class__(p)
def __mod__(self, rhs):
rhs = self.__class__(rhs)
p, r = divmodr(self.val, rhs.val, self._base)
return self.__class__(r)
def __rmod__(self, lhs):
lhs = self.__class__(lhs)
p, r = divmodr(lhs.val, self.val, self._base)
return self.__class__(r)
def __eq__(self, rhs):
rhs = self.__class__(rhs)
return rhs.val == self.val
def __pow__(self, rhs):
if isinstance(rhs, RingBase):
return self.__class__(self.val**rhs.val)
else:
return self.__class__(self.val**rhs)
def Ring(base, verbose=True):
class _R(RingBase):
_base = base
_verbose = verbose
return _R