项目欧拉#37:我的解决方案太慢了

时间:2012-12-10 12:08:36

标签: haskell optimization primes

我正在玩弄项目因素问题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

感谢所有优化指针!

1 个答案:

答案 0 :(得分:1)

您的代码中有两个错误,第一个

Prelude Data.Char Main> truncatablePrime 3797
False

第二,你的列表理解条件不正确。 (希望这不是一个剧透。)