P34 - 欧拉函数

2026-09-07 00:00    #Haskell   #99题   #数论  

P34 - 欧拉函数

Calculate Euler’s totient function φ(m)\varphi(m)

官方模块:Problems.P34 核心函数:totient


← P33 判断互质 | P35 质因数分解 →


题目描述

欧拉函数 φ(m)\varphi(m) 表示 1rm1\le r\le m 中与 mm 互质的整数个数。

函数签名

1totient :: Integral a => a -> a

实现

方法一:筛选计数(定义直译)

1totient :: Integral a => a -> a
2totient m
3  | m < 1     = error "totient: positive input required"
4  | otherwise = fromIntegral . length $ filter (coprime m) [1..m]

定义的直接翻译:从 1 到 m 筛出与 m 互质的数,再计数。P37 会用欧拉乘积公式将它优化。

方法二:递归遍历

1totient :: Integral a => a -> a
2totient 1 = 1
3totient n = go 1 0
4  where
5    go m acc
6      | m > n     = acc
7      | coprime m n = go (m + 1) (acc + 1)
8      | otherwise   = go (m + 1) acc

不用 filterlength,手动递归计数。减少了列表构造的内存开销。

方法三:内联 gcd 检查(不依赖 P33)

1totient :: Integral a => a -> a
2totient 1 = 1
3totient n = fromIntegral $ length [x | x <- [1..n], myGCD x n == 1]

不依赖 P33 的 coprime,直接调用 P32 的 myGCD。本质上和方法一相同,但依赖关系更浅。

方法对比

方法代码量依赖特点
filter + coprime1 行P33最抽象,语义清晰
递归遍历6 行P33无中间列表
列表推导 + myGCD1 行P32最少外部依赖

测试

1>>> totient 1
21
3>>> totient 10
44
5>>> totient 315
6144

因为 1、3、7、9 与 10 互质,所以 φ(10)=4\varphi(10)=4

参考