我正在尝试解决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,
,没有结尾。我不知道为什么会这样,因为如果我手动将函数应用于每个素数,我会得到正确的输出。
有人可以告诉我我的代码有什么问题吗,或者我的解决方法被证明是错误的?谢谢。
答案 0 :(得分:5)
Int
在这里不是一个很好的选择,因为使用10^x
可以计算很多数字。 Int
是Bounded
,因此绕过其上限:
> 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的答案是正确的。对于较大的数字,错误的结果表明我们有一些整数环绕算法错误的发生;这就是我发现它的方式。