P209: Calculate Euler's totient function phi(m)
计算欧拉函数。
在数论中,对正整数n,欧拉函数 是小于或等于n的正整数中与n互质的数的数目。此函数以其首名研究者欧拉命名,它又称为φ函数(由高斯所命名)或是欧拉总计函数(totient function,由西尔维斯特所命名)。
例如 ,因为1,3,5,7均和8互质。
欧拉函数实际上是模n的同余类所构成的乘法群(即环 的所有单位元组成的乘法群)的阶。这个性质与拉格朗日定理一起构成了欧拉定理的证明。wiki-euler
照例先写测试用例:
from python99.arithmetic.p209 import totient_phi
def test_totient_phi():
assert totient_phi(10) == 4
assert totient_phi(10090) == 4032
欧拉函数的值
(小于等于1的正整数中唯一和1互质的数就是1本身)。
若n是质数p的k次幂, ,因为除了p的倍数外,其他数都跟n互质。
欧拉函数是积性函数,即是说若m,n互质, 。证明:设A, B, C是跟m, n, mn互质的数的集,据中国剩余定理,和可建立双射(一一对应)的关系。(或者也可以从初等代数角度给出欧拉函数积性的简单证明) 因此 的值使用算术基本定理便知,
若
则 。
其中 是使得 整除 的最大整数 (这里 。
例如 wiki-euler
由欧拉函数的性质可知,先求出其所有质因数,再求出每一个质因数的(p为质因数,k为p在所有质因数中重复的之数),最后把结果累乘起来即为函数的值。
完整的代码实现:
# Calculate Euler's totient function phi(m)
from python99.arithmetic.p203 import prime_factors_mult
import functools
import operator
def totient_phi(n):
return functools.reduce(operator.mul,
[int((factor-1)*factor**(exp-1))
for factor, exp in prime_factors_mult(n)],
1)
在P203中已经实现了分解质因数,这里可以直接重用。prime_factors_mult
返回的是列表,其中每一个元素都二元组,二元组中第一个元素为质因数,第二个元素为质因数的幂。按公式计算每一个二元组。最后把结果用functools.reduce
累乘起来,就是欧拉函数的值。
参考文献
wiki-euler. https://zh.wikipedia.org/wiki/欧拉函数 ↩