确定给定数字是否是haskell中的素数

时间:2011-01-14 11:54:39

标签: algorithm haskell primes

所以我设计了以下函数来查看给定数字是否是Haskell中的素数(假设第一个素数是2):

isPrime k = length [ x | x <- [2..k], k `mod` x == 0)] == 1

即使可以被几个数字整除,它仍然存在继续评估的明显缺陷:(。当找到多个解决方案时,是否有任何理智的方式“切割”评估,使用列表理解?

另外,你会尝试哪些其他实现?我不是在这里寻找表现,我只是想看看是否还有其他更“冒险”的做法。

6 个答案:

答案 0 :(得分:22)

快速更改代码,使评估“短路”并依赖于Haskell列表的懒惰:

isPrime k = null [ x | x <- [2..k - 1], k `mod` x == 0]

k的第一个除数将导致列表非空,null的Haskell实现只会查看列表的第一个元素。

你应该只需要检查sqrt(k)然而[1]:

isPrime k = null [ x | x <- [2..isqrt k], k `mod` x == 0]

当然,如果您希望进行高性能素性测试,首选库。

[1] http://www.codecodex.com/wiki/Calculate_an_integer_square_root#Haskell

答案 1 :(得分:10)

以下是haskell.org中prime numbers in haskell的最佳资源

prime.hs github项目

答案 2 :(得分:6)

它可能不是直接相关的,但是关于在函数式语言中找到素数的主题,我发现Melissa E. O'Neill的The Genuine Sieve of Eratosthenes非常有趣。

答案 3 :(得分:4)

忽略素数问题,并关注更有效的length xs == n方法的狭隘观点:

hasLength :: Integral count => [a] -> count -> Bool
_        `hasLength` n | n < 0 = False
[]       `hasLength` n         = n == 0
(_ : xs) `hasLength` n         = xs `hasLength` (pred n)

isPrime k = [ x | x <- [2..k], k `mod` x == 0)] `hasLength` 1

答案 4 :(得分:4)

我喜欢这种方法:

首先使函数得到n的所有因子:

factors n = [x | x <- [1..n], mod n x == 0]

然后检查因子是否只是给定的数字和1,如果是,则数字是素数:

prime n = factors n == [1,n]

答案 5 :(得分:0)

这可能很愚蠢且效率低下(我是一个完整的 Haskell 新手),但是函数 isMyNumberPrime(在 ghci 中)似乎可以告诉您一个数字是否为素数。

factors n = [x | x <- [2..(n`div` 2)], mod n x == 0]
factormap n = fmap factors $ factors n
isMyNumberPrime n = case factormap n of [] -> True; _ -> False