DALGLI0/main.py

297 lines
7.6 KiB
Python
Raw Normal View History

2018-06-26 02:05:11 +02:00
import itertools
2018-06-27 19:14:55 +02:00
class Poly:
2018-06-27 22:09:17 +02:00
def __init__(self, int_mod, elements):
2018-06-27 19:14:55 +02:00
self.elements = {}
2018-06-27 22:09:17 +02:00
self.int_mod = int_mod
2018-06-27 19:14:55 +02:00
2018-06-28 01:46:46 +02:00
elements = list(reversed(elements))
z = 0
for i in elements:
if i != 0:
break
z += 1
elements = elements[z:]
2018-06-27 19:14:55 +02:00
i = len(elements) - 1
2018-06-28 01:46:46 +02:00
for e in elements:
2018-06-27 22:09:17 +02:00
self.elements[f"x{i}"] = e % self.int_mod
2018-06-27 19:14:55 +02:00
i -= 1
def __str__(self):
2018-06-27 22:09:17 +02:00
str_form = ""
deg = len(self.elements) - 1
for e in self.elements:
if self.elements[e] >= 0:
if e != f"x{deg}":
str_form += "+ "
else:
str_form += "- "
str_form += str(abs(self.elements[e]))
if e != "x0":
str_form += e[0] + "^" + e[1:] + " "
return str_form
2018-06-27 19:14:55 +02:00
def __mul__(self, other):
2018-06-27 22:09:17 +02:00
2018-06-27 23:04:58 +02:00
assert self.int_mod == other.int_mod
2018-06-27 22:09:17 +02:00
2018-06-27 19:14:55 +02:00
elements = {}
for e in self.elements:
for f in other.elements:
coefficient = self.elements[e] * other.elements[f]
degree = f"x{int(e[1:])+int(f[1:])}"
if elements.get(f"{degree}") is None:
2018-06-27 22:09:17 +02:00
elements[degree] = coefficient % self.int_mod
2018-06-27 19:14:55 +02:00
else:
2018-06-27 22:09:17 +02:00
elements[degree] += coefficient % self.int_mod
2018-06-27 19:14:55 +02:00
2018-06-28 00:06:30 +02:00
els = {}
for i in reversed(range(len(elements))):
els[f"x{i}"] = elements[f"x{i}"]
return Poly(self.int_mod, list(reversed(list(els.values()))))
2018-06-27 19:14:55 +02:00
2018-06-27 22:09:17 +02:00
def __pow__(self, power, modulo=None):
poly = Poly(self.int_mod, list(reversed(list(self.elements.values()))))
for i in range(power - 1):
poly *= poly
return poly
def __add__(self, other):
2018-06-27 23:04:58 +02:00
assert self.int_mod == other.int_mod
2018-06-27 22:09:17 +02:00
elements = self.elements.copy()
for f in other.elements:
if f in elements:
elements[f] += other.elements[f]
else:
elements[f] = other.elements[f]
2018-06-27 23:04:58 +02:00
els = {}
for i in reversed(range(len(elements))):
els[f"x{i}"] = elements[f"x{i}"]
return Poly(self.int_mod, list(reversed(list(els.values()))))
def __sub__(self, other):
assert self.int_mod == other.int_mod
elements = self.elements.copy()
for e in other.elements:
if e in elements:
elements[e] -= other.elements[e]
else:
elements[e] = -other.elements[e]
els = {}
for i in reversed(range(len(elements))):
els[f"x{i}"] = elements[f"x{i}"]
return Poly(self.int_mod, list(reversed(list(els.values()))))
2018-06-27 22:09:17 +02:00
def __truediv__(self, other):
2018-06-28 00:06:30 +02:00
assert self.int_mod == other.int_mod
2018-06-27 22:09:17 +02:00
if other.is_empty():
raise ZeroDivisionError("Polynomial is empty")
2018-06-28 00:06:30 +02:00
poly = Poly(self.int_mod, list(reversed(list(self.elements.values()))))
fdeg = len(poly.elements) - 1
2018-06-27 22:09:17 +02:00
sdeg = len(other.elements) - 1
2018-06-28 01:46:46 +02:00
# print(poly)
# print(poly.elements)
# print(fdeg)
# print(sdeg)
2018-06-28 00:06:30 +02:00
while fdeg >= sdeg:
2018-06-28 01:46:46 +02:00
# coefficient = poly.elements[f"x{fdeg}"] / other.elements[f"x{sdeg}"]
# coefficient %= poly.int_mod
# coefficient = 0
coefficient = other.elements[f"x{sdeg}"]
for i in range(1, poly.int_mod):
if (coefficient * i) % poly.int_mod == poly.elements[f"x{fdeg}"]:
coefficient = i
break
2018-06-27 22:09:17 +02:00
degree = fdeg - sdeg
2018-06-28 00:06:30 +02:00
divpoly = [0 for x in range(degree + 1)]
divpoly[degree] = coefficient
divpoly = Poly(poly.int_mod, divpoly)
mulpoly = divpoly * other
2018-06-28 01:46:46 +02:00
# print(poly)
2018-06-28 00:06:30 +02:00
poly -= mulpoly
2018-06-28 01:46:46 +02:00
# print(poly)
2018-06-28 00:06:30 +02:00
for i in poly.elements.keys():
if poly.elements[f"{i}"] != 0:
fdeg = int(i[1:])
break
return poly
2018-06-27 22:09:17 +02:00
2018-06-28 01:46:46 +02:00
def __mod__(self, other):
dividened = Poly(self.int_mod,
list(reversed(list(self.elements.values()))))
divisor = Poly(self.int_mod,
list(reversed(list(other.elements.values()))))
div_result = dividened / divisor
els = []
for e in div_result.elements.keys():
if div_result.elements[e] != 0:
els.append(div_result.elements[e])
div_result = Poly(self.int_mod, list(reversed(list(els))))
# #
# # print(dividened)
# # print(divisor)
# # print(div_result)
# #
# print(div_result.elements)
# dividened = Poly(dividened.int_mod,
# list(reversed(list(divisor.elements.values()))))
# divisor = Poly(divisor.int_mod,
# list(reversed(list(div_result.elements.values()))))
# print(dividened)
# print(divisor)
# div_result = dividened / divisor
#
# print()
# print(dividened)
# print(divisor)
# print(div_result)
# print()
# while True:
# dividened = Poly(dividened.int_mod,
# list(reversed(list(divisor.elements.values()))))
# divisor = Poly(divisor.int_mod,
# list(reversed(list(div_result.elements.values()))))
# div_result = dividened / divisor
#
# if div_result.is_empty():
# break
# print(div_result)
return div_result
2018-06-27 22:09:17 +02:00
def is_empty(self):
for e in self.elements:
if self.elements[e] != 0:
return False
return True
2018-06-26 02:05:11 +02:00
class PolyIntField:
2018-06-27 22:09:17 +02:00
def __init__(self, int_mod, poly_mod):
self.int_modulo = int_mod
self.poly_modulo = Poly(int_mod, poly_mod)
product = list(itertools.product([x for x in range(0, int_mod)],
repeat=len(poly_mod) - 1))
self.elements = []
for p in product:
p = list(p)
p = [x % int_mod for x in p]
self.elements.append(Poly(int_mod, p))
2018-06-26 02:05:11 +02:00
2018-06-27 19:14:55 +02:00
def get_nilpotents(self):
nilpotents = []
# for element in self.elements:
2018-06-26 02:05:11 +02:00
if __name__ == "__main__":
2018-06-28 01:46:46 +02:00
# a = Poly(5, [1, 0, 4, 0, 2, 1, 0, 0])
# # print(a)
# b = Poly(5, [4, 0, 0, 0, 1])
# # print(b)
# # print(a + b)
# print(a % b)
# d = Poly(5, [3, 1, 4])
# # print(d)
# e = Poly(5, [4, 0, 0, 0, 1])
# # print(e)
# print(e / d)
# c = Poly(5, [4, 0, 0, 0, 1])
# d = Poly(5, [3, 1, 4, 0, 0, 0])
# print(c)
# print(d)
# print(c % d)
# e = Poly(10, [-4, 0, -2, 1])
# f = Poly(10, [-3, 1])
# print(e / f)
2018-06-28 00:06:30 +02:00
2018-06-28 01:46:46 +02:00
# print((a % b).elements)
# d = Poly(10, [2, 0, 6, 0, 1])
# e = Poly(10, [5, 0, 1])
# print(d / e)
2018-06-28 00:06:30 +02:00
# print(a - Poly(10, [0, 0, -3, 1]))
# p = Poly(5, [-4, 0, -2, 1])
2018-06-27 22:09:17 +02:00
# print(p)
# c = p * p
# print(c.elements)
# print(c)
# print(p ** 2)
2018-06-27 23:04:58 +02:00
2018-06-27 22:09:17 +02:00
# print(p)
# print(d)
# print(p)
# print(p + d)
2018-06-28 00:06:30 +02:00
# d = Poly(5, [-3, 1])
# g = Poly(5, [1, 2, 1])
2018-06-27 23:04:58 +02:00
# print(d)
# print(g)
2018-06-28 00:06:30 +02:00
# print()
#
# # print(g)
# print(g - d)
# print(d - g)
#
# print()
2018-06-27 23:04:58 +02:00
# print(d + g)
2018-06-28 00:06:30 +02:00
# print(g + d)
#
# print()
# print(d * g)
# print(g * d)
2018-06-27 23:04:58 +02:00
# print(d)
# print(g)
2018-06-27 22:09:17 +02:00
# print(g - d)
# print(p / d)
# print(p.elements[0])
2018-06-27 19:14:55 +02:00
# a = PolyIntField(3, [1, 1, 2, 2])
2018-06-27 22:09:17 +02:00
# for e in a.elements:
# print(e.elements)
# print()
# print(a.elements[4])
# print(a.elements[8])
# print(a.elements[4] * a.elements[8])
# a.elements[3] / a.elements[1]