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
| #! python3
# coding: utf-8
from termcolor import cprint
from math import sqrt, gcd
from timeit import timeit
def phi_euler(n):
"""
Calcul de l'indicatrice d'Euler par différences
Méthode de yoshi le 24-10-2013 18:18:22
Sur http://www.bibmath.net/forums/viewtopic.php?id=6336
Dans le message n° 10
"""
def diviseurs(n):
D, racine = [1], int(sqrt(n))
fin = racine+1
for d in range(2, fin):
if n % d == 0:
D.extend([d, n//d])
D = sorted(set(D))
return D
D = diviseurs(n)
phi = [1]
for div in D:
if div > 1:
D_i, q = [d for d in D if div % d == 0 and d < div], 0
for d in D_i:
q += phi[D.index(d)]
p = div - q
phi.append(p)
return n - sum(phi)
"""Cette méthode est plus rapide que la méthode brute,
mais enore trop lente pour les grands nombres"""
def phi_euler_gcd(n):
lst = []
for k in range(1, n+1):
if gcd(n, k) == 1:
lst.append(k)
return len(lst)
if __name__ == "__main__":
'''
N = 200000
t1 = timeit("phi_euler(N)", setup="from __main__ import phi_euler, N", number=500)
t2 = timeit("phi_euler_gcd(N)",
setup="from __main__ import phi_euler_gcd, N", number=500)
cprint("""phi_euler = {} ; phi_euler_gcd = {}""".format(t1, t2), "red")
# phi_euler = 0.2173256 ; phi_euler_gcd = 26.545367900000002
'''
N = 20000000000
cprint(timeit("phi_euler(N)", setup="from __main__ import phi_euler, N", number=1), "red")
# 0.033877199999999996 |