DALGLI0/hw4.py

84 lines
2.6 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(phi+1):
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()