diff --git a/hw2.py b/hw2.py deleted file mode 100644 index c15a1df..0000000 --- a/hw2.py +++ /dev/null @@ -1,121 +0,0 @@ -import sys -import ast -import operator -from fractions import gcd - -class Polynomial(): - def __init__(self, lst, mod): - super().__init__() - self.poly = list(map(lambda x: x % mod, lst)) - self.mod = mod - self.normalize() - def normalize(self): - while self.poly and self.poly[-1] == 0: - self.poly.pop() - - def arithm(self, p1, p2, op): - len_p1, len_p2= len(p1.poly), len(p2.poly) - res = [0] * max(len_p1, len_p2) - if len_p1 > len_p2: - for _ in range(len_p1-len_p2): - p2.poly.append(0) - else: - for _ in range(len_p2-len_p1): - p1.poly.append(0) - - for i in range(len(res)): - res[i] = op(p1.poly[i], p2.poly[i]) % self.mod - return Polynomial(res, self.mod) - - def __add__(self, p2): - return self.arithm(self, p2, operator.add) - - def __sub__(self, p2): - return self.arithm(self, p2, operator.sub) - - def __mul__(self, p2): - res = [0]*(len(self.poly)+len(p2.poly)-1) - for i, x1 in enumerate(self.poly): - for j, x2 in enumerate(p2.poly): - res[i+j] += x1 * x2 % self.mod - return Polynomial(res, self.mod) - - def __truediv__(self, p2): - p1 = self - m = self.mod - - if len(p1.poly) < len(p2.poly): - return p1 - - if len(p2.poly) == 0: - raise ZeroDivisionError - - divisor_coeff = p2.poly[-1] - divisor_exp = len(p2.poly) - 1 - while len(p1.poly) >= len(p2.poly): - max_coeff_p1 = p1.poly[-1] #wspolczynnik przy najwyzszej potedze - try: - tmp_coeff = modDiv(max_coeff_p1, divisor_coeff, m) - except ZeroDivisionError as e: - raise e - - tmp_exp = len(p1.poly)-1 - divisor_exp - '''tmp to pomocniczy wielomian o reprezentacji [0, 0, .., c^n], gdzie c^n to - mnożnik w danym kroku algorytmu dzielenia w słupku. - Następnie mnożymy go z wielomianem-dzielnikiem (p2) i - odejmujemy (sub) od wielomianu-dzielnej (p1)''' - tmp = [] - for i in range(tmp_exp): - tmp.append(0) - tmp.append(tmp_coeff) - sub = Polynomial(tmp, m) * p2 - p1 = p1 - sub - p1.normalize() #obcinamy zbędne zera dopisane do wielomianu podczas odejmowania - return Polynomial(p1.poly, m) - - def poly_gcd(self, p2): - p1 = self - try: - divisible = p2 - except ZeroDivisionError as e: - raise e - if p2.poly == []: - return p1 - return p2.poly_gcd(p1 / p2) - -def modDiv(a, b, m): # a*b^-1 (mod m) - if gcd(b, m) != 1: - raise ZeroDivisionError - else: - return (a * modinv(b, m)) % m - -#rozszerzony algorytm euklidesa -def egcd(a, b): - if a == 0: - return (b, 0, 1) - else: - g, y, x = egcd(b % a, a) - return (g, x - (b // a) * y, y) - -def modinv(a, m): - g, x, y = egcd(a, m) - return x % m - -def main(): - n, p1, p2 = int(sys.argv[1]), ast.literal_eval(sys.argv[2]), ast.literal_eval(sys.argv[3]) - P1 = Polynomial(p1, n) - P2 = Polynomial(p2, n) - mul = (P1 * P2).poly - try: - div = (P1 / P2).poly - except ZeroDivisionError as e: - div = e - try: - gcd = P1.poly_gcd(P2).poly - except ZeroDivisionError as e: - gcd = e - print([mul, div, gcd]) - - -if __name__ == '__main__': - main() \ No newline at end of file