This repository was archived by the owner on Dec 11, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathEx2.py
More file actions
141 lines (120 loc) · 3.74 KB
/
Ex2.py
File metadata and controls
141 lines (120 loc) · 3.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
import math as ma
import multiprocessing as mp
import time
def first_test(n):
""" test naïf de primalité
retourne True si l'entier est premier, et inversement
n : un entier naturel
"""
for a in range(2, int(ma.sqrt(n) + 1)):
if n % a == 0:
return False
return True
def pi(x):
"""retourne le nombre de premiers inférieurs à x
X : un réel
"""
cpt = 0
for n in range(1, int(x)):
if first_test(n):
cpt += 1
return cpt
def gen_carmichael(t):
"""retourne tous les nombres de Carmichael inférieurs à x
t : un réel
"""
res = []
for x in range(3, int(t), 2): # les nombres de Carmichael sont impairs
valid = False
for y in range(2, x):
if ma.gcd(x, y) == 1:
if pow(y, x-1, x) != 1:
valid = False
break
else:
valid = True
if valid:
res.append(x)
return res
def worker_proc(x):
valid = False
for y in range(2, x):
if ma.gcd(x, y) == 1:
if pow(y, x - 1, x) != 1:
return
else:
valid = True
if valid:
print(x)
def gen_carmichael_mp(t):
"""retourne tous les nombres de Carmichael inférieurs à t
version multiprocess
t : un réel
"""
pool = mp.Pool(processes=mp.cpu_count())
pool.map(worker_proc, range(3, int(t), 2))
def gen_carmichael_3(k):
""" genère les nombres de Carmicheal de longueur binaire k à partir de trois diviseurs premiers
k : un entier
"""
# t = int(t)
prime = []
for n in range(3, 2 ** k, 2):
if first_test(n):
prime.append(n)
res = []
for i_a, a in enumerate(prime):
for i_b, b in enumerate(prime[:i_a]):
ab = a * b
for c in prime[:i_b]:
# on a obtenu 3 premiers, on teste si leur produit est Carmichael
# worker_proc(a * b * c)
tst = ab * c - 1
if tst.bit_length() != k:
continue
if tst % 2 == 0 and tst % (a - 1) == 0 and tst % (b - 1) == 0 and tst % (c - 1) == 0 and a % (b * c) != 0:
res.append(tst + 1)
return sorted(res)
def gen_carmichael_3_all(t):
""" genère un nombre de Carmicheal inférieur t à partir de trois diviseurs premiers
version sans contrainte de taille
"""
t = int(t)
prime = []
for n in range(3, t, 2):
if first_test(n):
prime.append(n)
res = []
for i_a, a in enumerate(prime):
for i_b, b in enumerate(prime[:i_a]):
ab = a * b
for c in prime[:i_b]:
tst = ab * c - 1
if tst % 2 == 0 and tst % (a - 1) == 0 and tst % (b - 1) == 0 and tst % (c - 1) == 0 and a % (b * c) != 0:
res.append(tst + 1)
return sorted(res)
def gen_carmichael_2(p):
"""retourne tous les nombre de carmichael de la forme pqr pour un p donné"""
prime = []
for n in range(3, 2 * p * (p ** 2 + 1), 2):
if n == p:
continue
if first_test(n):
prime.append(n)
res = []
for i_r, r in enumerate(prime):
for q in prime[:i_r]:
tst = p * q * r - 1
if tst % 2 == 0 and tst % (p - 1) == 0 and tst % (q - 1) == 0 and tst % (r - 1) == 0 and r % (p * q) != 0:
res.append(tst + 1)
return sorted(res)
if __name__ == '__main__':
t = time.time()
gen_carmichael_mp(10000)
print("mt : ", str(time.time() - t))
t = time.time()
print(gen_carmichael(64000))
print("naif : ", str(time.time() - t))
t = time.time()
print(gen_carmichael_3_all(100))
print("3 : ", str(time.time() - t))