From 39addf92dafb4ed1f22f340e7b90cdbd5c421fa3 Mon Sep 17 00:00:00 2001 From: Szymon Wojciechowski Date: Thu, 28 Jun 2018 08:57:27 +0000 Subject: [PATCH] Upload files to 'Zadanie-4' --- Zadanie-4/poly.py | 83 +++++++++++++++++++++++++++++++++++ Zadanie-4/quotient_ring.py | 88 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 171 insertions(+) create mode 100644 Zadanie-4/poly.py create mode 100644 Zadanie-4/quotient_ring.py diff --git a/Zadanie-4/poly.py b/Zadanie-4/poly.py new file mode 100644 index 0000000..ab3ac44 --- /dev/null +++ b/Zadanie-4/poly.py @@ -0,0 +1,83 @@ +import sys +import ast + +class Polynomial: + + n = 0 + + def __init__(self, coeff_list): + self.degree = len(coeff_list) - 1 + self.coefficients = [x % Polynomial.n for x in coeff_list] + + def __pow__(self, n): + result = self + for i in range(n): + result = Polynomial.multiply(result, result) + return result + + @staticmethod + def add(p1, p2): + result = [] + f = p1.coefficients + g = p2.coefficients + if len(f) >= len(g): + result = f + for i in range(len(g)): + result[i] = f[i] + g[i] + else: + result = g + for i in range(len(f)): + result[i] = f[i] + g[i] + result = [x % int(Polynomial.n) for x in result] + return Polynomial(result) + + @staticmethod + def multiply(p1, p2): + result = [0] * (p1.degree + p2.degree + 1) + f = p1.coefficients + g = p2.coefficients + for i in range(len(f)): + for j in range(len(g)): + result[i+j] += f[i] * g[j] + result = [x % int(Polynomial.n) for x in result] + return Polynomial(result) + + @staticmethod + def divide(p1, p2): + + def inverse(x): + for i in range(1, int(Polynomial.n)): + r = (i * x) % int(Polynomial.n) + if r == 1: + break + else: + raise ZeroDivisionError + return i + + if p1.degree < p2.degree: + return p1 + f = p1.coefficients + g = p2.coefficients + g_lead_coef = g[-1] + g_deg = p2.degree + while len(f) >= len(g): + f_lead_coef = f[-1] + tmp_coef = f_lead_coef * inverse(g_lead_coef) + tmp_exp = len(f) - 1 - g_deg + tmp = [] + for _ in range(tmp_exp): + tmp.append(0) + tmp.append(tmp_coef) + tmp_poly = Polynomial(tmp) + sub = Polynomial.multiply(p2, tmp_poly) + f = [x - y for x, y in zip(f, sub.coefficients)] + f = [x % int(Polynomial.n) for x in f] + while f and f[-1] == 0: + f.pop() + return Polynomial(f) + + @staticmethod + def gcd(p1, p2): + if len(p2.coefficients) == 0: + return p1 + return Polynomial.gcd(p2, Polynomial.divide(p1, p2)) diff --git a/Zadanie-4/quotient_ring.py b/Zadanie-4/quotient_ring.py new file mode 100644 index 0000000..f9e963b --- /dev/null +++ b/Zadanie-4/quotient_ring.py @@ -0,0 +1,88 @@ +from poly import Polynomial as P +import sys +import ast + +class QuotientRing: + + def __init__(self, coeffs): + self.fx = P(coeffs) + self.remainder_set = self.create_remainder_set() + self.invertible_elements = self.get_invertible_elements() + self.zero_divisors = self.get_zero_divisors() + self.nilpotent_elements = self.get_nilpotent_elements() + self.idempotent_elements = self.get_idempotent_elements() + + def create_remainder_set(self): + remainders = [] + rem = [0] + i = 0 + while len(rem) < len(self.fx.coefficients): + remainders.append(P(rem)) + i = (i + 1) % P.n + rem[0] = i + if i == 0: + if len(rem) == 1: + rem.append(1) + else: + rem[1] += 1 + for j in range(1, len(rem)): + if rem[j] == 0 or rem[j] % P.n != 0: + break + tmp = rem[j] % P.n + rem[j] = 0 + if tmp == 0: + if (j + 1) < len(rem): + rem[j+1] += 1 + else: + rem.append(1) + return remainders + + def get_invertible_elements(self): + invertible_elements = [] + for i in self.remainder_set: + if i.coefficients != [0] and len(P.gcd(self.fx, i).coefficients) == 1: + invertible_elements.append(i) + return invertible_elements + + def get_zero_divisors(self): + zero_diviors = [] + for i in self.remainder_set: + if i not in self.invertible_elements: + zero_diviors.append(i) + return zero_diviors + + def get_nilpotent_elements(self): + nilpotent_elements = [] + for i in self.zero_divisors: + for j in range(1, len(self.invertible_elements) + 1): + if i.coefficients == [0] or len(P.divide(i**j, self.fx).coefficients) == 0: + nilpotent_elements.append(i) + break + return nilpotent_elements + + def get_idempotent_elements(self): + idempotent_elements = [] + for i in self.remainder_set: + if P.divide(i**2, self.fx).coefficients == P.divide(i, self.fx).coefficients: + idempotent_elements.append(i) + return idempotent_elements + + +def main(): + P.n = int(sys.argv[1]) + coeffs = ast.literal_eval(sys.argv[2]) + Q = QuotientRing(coeffs) + + ans = [ + [x.coefficients for x in Q.invertible_elements], + [x.coefficients for x in Q.zero_divisors], + [x.coefficients for x in Q.nilpotent_elements], + [x.coefficients for x in Q.idempotent_elements] + ] + + for i in range(len(ans)): + print(ans[i]) + + +if __name__ == '__main__': + main() \ No newline at end of file