Haskell的Euler 26

时间:2019-02-05 07:09:41

标签: haskell

我正在尝试解决Haskell的Euler项目中的问题#26,但是我遇到了一些问题。

我设法弄清楚了倒数的重复周期仅与其质数有关,所以我认为我只需要找出循环周期最长的质数的倒数即可。所以我在Haskell中写了一个算法:

isPrime :: Int -> Bool
isPrime k
    | k <= 1    = error "Seriously?"
    | otherwise = null [ x | x <- [2..floor(sqrt(fromIntegral k))], k `mod` x == 0]

lp = [x | x <- [7..1000], isPrime x]

s = map (\n -> head [x | x <- [ceiling(logBase 10 (fromIntegral n))..], 10^x `mod` n == 1]) lp

main::IO()
main = print $ maximum s

但是,它无法产生答案。我尝试使用lamda,它可以产生重复周期的数字,并带有几个质数,并且设法获得正确的数字计数(我希望算法不会出现问题)。我还检查了列表s的输出,该列表产生了[6,2,6,16,18,45,23,15,3,5,63,,没有结尾。我不知道为什么会这样,因为如果我手动将函数应用于每个素数,我会得到正确的输出。

有人可以告诉我我的代码有什么问题吗,或者我的解决方法被证明是错误的?谢谢。

1 个答案:

答案 0 :(得分:5)

Int在这里不是一个很好的选择,因为使用10^x可以计算很多数字。 IntBounded,因此绕过其上限:

> maxBound :: Int
9223372036854775807

> (maxBound :: Int) + 1
-9223372036854775808

完全省略isPrime的签名,我们得到

> :t lp
lp :: Integral b => [b]

尝试

> map (\n -> (n, head [x | x <- [ceiling(logBase 10 (fromIntegral n))..],
                           10^x `mod` n == 1])) 
      (lp :: [Int])
[(7,6),(11,2),(13,6),(17,16),(19,18),(23,45),(29,23),(31,15),(37,3),(41,5),(43,63),
 (47,Interrupted.

我们看到您的计算陷入了47。但是使用[Integer](或完全不使用,因此它本身默认为Integer),我们可以成功获得完整的结果。您只是误解了。重新阅读问题陈述,您将看到。

(同样,以上代码段中43的答案是错误的,而7、11、13的答案是正确的。对于较大的数字,错误的结果表明我们有一些整数环绕算法错误的发生;这就是我发现它的方式。