我正在玩弄项目因素问题37.问题如下:
3797号有一个有趣的属性。作为素数本身,可以从左到右连续删除数字,并在每个阶段保持素数:3797,797,97和7.同样,我们可以从右到左工作:3797,379,37和3。
找到从左到右和从右到左都可截断的仅有11个素数之和。
注意:2,3,5和7不被视为可截断的素数。
这是我的代码:
import Data.Char
prime n
| n < 2 = False
| n == 2 = True
| length [x | x <- [2..(floor . sqrt $ fromIntegral n)], n `mod` x == 0] == 0 = True
| otherwise = False
truncateList xs = take (length xs) $ iterate init xs
truncateSteps n = truncateList nn ++ truncateList rn
where
nn = map digitToInt $ show n
rn = reverse nn
truncatablePrime n = and $ map (\ns -> prime $ foldl (\x y -> 10 * x + y) 0 ns) $ truncateSteps n
main = print $ sum $ take 11 $ [n | n <- [9,11..], notElem 5 $ map digitToInt $ show n, truncatablePrime n]
我相信如果完成,我的代码将产生正确的结果。这简直太慢了。我已经优化了一些东西,比如不计算包含数字'5'的数字,只检查数字的平方根的'primeness',但这还不够。
我想要一些我可以研究的其他优化提示。现在,请记住,我是haskell的新成员,但建议你认为值得一提。
更新 这是完成的解决方案,在我的机器上运行大约1秒钟:https://gist.github.com/4250615
感谢所有优化指针!
答案 0 :(得分:1)
您的代码中有两个错误,第一个
Prelude Data.Char Main> truncatablePrime 3797
False
第二,你的列表理解条件不正确。 (希望这不是一个剧透。)