Compare commits

...

2 Commits

Author SHA1 Message Date
76bbe95c2f Prześlij pliki do '' 2018-06-06 20:05:39 +00:00
b0323052f7 Prześlij pliki do ''
python hw.py
2018-05-30 17:44:28 +00:00
2 changed files with 168 additions and 0 deletions

47
hw.py Normal file
View File

@ -0,0 +1,47 @@
from fractions import gcd
class Modulo:
def __init__(self, n):
self.elems = list(range(n))
self.n = n
self.reversibles = self.get_reversibles()
self.idempotent = self.get_idempotent()
self.zero_divisors = self.get_zero_divisors()
self.nilpotent = self.get_nilpotent()
'''elementy odwracalne to te, ktorych nwd z n jest rowne 1'''
def get_reversibles(self):
return list(filter(lambda x: gcd(x, self.n) == 1, self.elems))
'''nie rozwazamy elementow odwracalnych ani liczby 0
#dzielnik zera nie moze byc elementem odwracalnym'''
def get_zero_divisors(self):
potential_zeros = [ elem for elem in self.elems if elem not in self.reversibles ][1:]
results = []
for elem in potential_zeros:
for elem2 in potential_zeros:
if (elem * elem2) % self.n == 0:
results.append(elem)
break
return list(results)
def get_idempotent(self):
'''element idempotentny => a^2 przystaje do a'''
return list(filter(lambda x: x*x % self.n == x, self.elems))
def get_nilpotent(self):
'''jesli pierscien nie zawiera dzielnikow zera, to nie zawiera takze elementow
nilpotentnych; wystarczy sprawdzic wsrod dzielnikow zera '''
potential_nils = self.zero_divisors
phi = len(self.reversibles) #funkcja fi
results = []
for elem in potential_nils:
for i in range(1, phi+1):
if elem**i % self.n == 0:
results.append(elem)
break
return results
def main():
m = Modulo(int(input()))
print([m.reversibles, m.zero_divisors, m.nilpotent, m.idempotent])
if __name__ == '__main__':
main()

121
hw2.py Normal file
View File

@ -0,0 +1,121 @@
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()