【发布时间】:2012-01-18 03:58:43
【问题描述】:
为了帮助我学习 Haskell,我正在解决 Project Euler 中的问题。解决每个问题后,我会对照 Haskell wiki 检查我的解决方案,以尝试学习更好的编码实践。这里是the solution 到problem 3:
primes = 2 : filter ((==1) . length . primeFactors) [3,5..]
primeFactors n = factor n primes
where
factor n (p:ps)
| p*p > n = [n]
| n `mod` p == 0 = p : factor (n `div` p) (p:ps)
| otherwise = factor n ps
problem_3 = last (primeFactors 317584931803)
我对此的幼稚解读是primes 是根据primeFactors 定义的,而primeFactors 是根据primes 定义的。所以评估primeFactors 9 将遵循这个过程:
- 评估
factor 9 primes。 - 向
primes询问其第一个元素,即 2。 - 向
primes询问下一个元素。 - 作为此过程的一部分,请评估
primeFactors 3。 - 向
primes询问其第一个元素,即 2。 - 向
primes询问下一个元素。 - 作为此过程的一部分,请评估
primeFactors 3。 - ...
换句话说,步骤 2-4 将无限重复。显然我错了,因为算法终止了。我在这里犯了什么错误?
【问题讨论】:
-
因为,正如这里的答案所说,
primeFactors仅访问primes直到素数的平方超过被测试的数字,该代码等效于primes = 2:[n | n<-[3..], all ((> 0).rem n) $ takeWhile ((<= n).(^2)) primes],这显然是非循环的.
标签: haskell primes factorization