84 lines
2.7 KiB
Python
84 lines
2.7 KiB
Python
|
from poly import Polynomial
|
||
|
from sys import argv
|
||
|
from ast import literal_eval
|
||
|
from fractions import gcd
|
||
|
|
||
|
class QuotientRing():
|
||
|
def __init__(self, f, m):
|
||
|
self.f = Polynomial(f, m)
|
||
|
self.m = m
|
||
|
self.remainders = self.remainders()
|
||
|
self.reversibles = self.reversibles()
|
||
|
self.zero_divisors = self.zero_divisors()
|
||
|
self.idempotent = self.idempotent()
|
||
|
self.nilpotent = self.nilpotent()
|
||
|
|
||
|
def remainders(self): #n - exponent
|
||
|
rems = [] #lista reszt
|
||
|
m = self.m
|
||
|
t = [0]
|
||
|
i = 0
|
||
|
while len(t) < len(self.f.poly):
|
||
|
rems.append(Polynomial(t, m))
|
||
|
i = (i + 1) % m
|
||
|
t[0] = i
|
||
|
if i == 0:
|
||
|
if len(t) == 1:
|
||
|
t.append(1)
|
||
|
else:
|
||
|
t[1] += 1
|
||
|
for j in range(1, len(t)):
|
||
|
if t[j] == 0 or t[j] % m != 0:
|
||
|
break
|
||
|
temp = t[j] % m
|
||
|
t[j] = 0
|
||
|
if temp == 0:
|
||
|
if (j + 1) < len(t):
|
||
|
t[j+1] += 1
|
||
|
else:
|
||
|
t.append(1)
|
||
|
return rems
|
||
|
|
||
|
def reversibles(self):
|
||
|
return [ rem for rem in self.remainders if len(rem.poly_gcd(self.f).poly) == 1 ]
|
||
|
|
||
|
#dopelnienie elementow odwracalnych
|
||
|
def zero_divisors(self):
|
||
|
return [ rem for rem in self.remainders if rem not in self.reversibles ]
|
||
|
|
||
|
def idempotent(self):
|
||
|
idems = []
|
||
|
for rem in self.remainders:
|
||
|
if (rem * rem / self.f) == (rem / self.f):
|
||
|
idems.append(rem)
|
||
|
try:
|
||
|
if idems[0].poly == []: #implementacja wielomianow ucina zera
|
||
|
idems[0].poly = [0]
|
||
|
except IndexError:
|
||
|
return idems
|
||
|
return idems
|
||
|
|
||
|
def nilpotent(self):
|
||
|
nils = []
|
||
|
phi = len([ i for i in range(1, self.m) if gcd(i, self.m) == 1 ])
|
||
|
for zero_div in self.zero_divisors:
|
||
|
for i in range(self.m):
|
||
|
if len((zero_div ** i / self.f).poly) == 0:
|
||
|
nils.append(zero_div)
|
||
|
break
|
||
|
return nils
|
||
|
|
||
|
def main():
|
||
|
m = int(argv[1])
|
||
|
f = literal_eval(argv[2])
|
||
|
qr = QuotientRing(f, m)
|
||
|
out = [
|
||
|
[ rev.poly for rev in qr.reversibles ],
|
||
|
[ zero_div.poly for zero_div in qr.zero_divisors ],
|
||
|
[ nil.poly for nil in qr.nilpotent ],
|
||
|
[ idem.poly for idem in qr.idempotent ]
|
||
|
]
|
||
|
print(*out, sep='\n')
|
||
|
|
||
|
if __name__ == '__main__':
|
||
|
main()
|