素数
一些最突出的变种:
低于 100
import Data.List ( (\\) )
ps100 = ((([2..100] \\ [4,6..100]) \\ [6,9..100]) \\ [10,15..100]) \\ [14,21..100]
-- = (((2:[3,5..100]) \\ [9,15..100]) \\ [25,35..100]) \\ [49,63..100]
-- = (2:[3,5..100]) \\ ([9,15..100] ++ [25,35..100] ++ [49,63..100])
无限
Eratosthenes 筛选,使用数据 ordlist 包 :
import qualified Data.List.Ordered
ps = 2 : _Y ((3:) . minus [5,7..] . unionAll . map (\p -> [p*p, p*p+2*p..]))
_Y g = g (_Y g) -- = g (g (_Y g)) = g (g (g (g (...)))) = g . g . g . g . ...
传统
(次优试验筛)
ps = sieve [2..]
where
sieve (x:xs) = [x] ++ sieve [y | y <- xs, rem y x > 0]
-- = map head ( iterate (\(x:xs) -> filter ((> 0).(`rem` x)) xs) [2..] )
最佳试验分工
ps = 2 : [n | n <- [3..], all ((> 0).rem n) $ takeWhile ((<= n).(^2)) ps]
-- = 2 : [n | n <- [3..], foldr (\p r-> p*p > n || (rem n p > 0 && r)) True ps]
过渡
从试验师到筛选 Eratosthenes:
[n | n <- [2..], []==[i | i <- [2..n-1], j <- [0,i..n], j==n]]
最短的代码
nubBy (((>1).).gcd) [2..] -- i.e., nubBy (\a b -> gcd a b > 1) [2..]
nubBy
也来自 Data.List
,就像 (\\)
。