找到n使得f n在Haskell中最大化

时间:2012-09-05 01:50:15

标签: haskell

我正在使用Project Euler问题来学习Haskell,我在许多这些问题中找到了一个反复出现的主题,我需要找到一个值n,它为函数{{f n提供一些属性(通常是最小值或最大值){ 1}}。在构建解决方案时,我经常发现创建对(n, f n)对的列表很方便。这有助于我快速查看我的逻辑中是否有任何错误,因为我可以检查问题陈述中给出的示例。然后我“过滤”了提供解决方案的单对。我对问题47的解决方案是一个例子:

-- Problem 47

import Data.List
import ProjectEuler

main = do
    print (fst (head (filter (\(n, ds) -> (all (==consecutiveCount) ds)) 
                       (zip ns (map (map length) 
                                    (map (map primeDivisors) consecutives))))))
    where consecutiveCount = 4
          consecutive n start = take n [start..]
          consecutives = map (consecutive consecutiveCount) ns
          ns = [1..]

在我看来,有更多的“haskelly”方式来做到这一点。有吗?

2 个答案:

答案 0 :(得分:6)

使用maximumBy中的Data.List与来自comparing的{​​{1}},例如

Data.Ord

这将为每个maximumBy (comparing snd) [(n, f n) | n <- ns] 计算一次f。如果n计算成本低廉,您可以使用更简单的

f

答案 1 :(得分:0)

好吧,你可以把你的功能写成

main = print $ fst $ head 
         [ (x,ds) | x <- [1..]
                  , let ds=map primeDivisors [x..x+3], all ((==4).length) ds]

你可以认为使用Control.Arrow的{​​{1}}或“扇出”更“Haskelly”

(&&&)

为了能够先调试代码来尝试简单的例子,你通常会把它作为一个函数,抽象出感兴趣的变量,如下所示:

   filter (all ((==4).length).snd) 
          . map (id &&& (\x-> map primeDivisors [x..x+3])) $ [1..]

搜索test n m = [ x | x <- [1..], all (==n) $ map (length.primeDivisors) [x..x+m-1]] 个连续数字,每个数字都有m个不同的素因子。实际上没有必要在最终代码中携带分析。