简体   繁体   English

找到n使fk在Haskell中最大化

[英]Finding n such that f n is maximized in Haskell

I am using Project Euler problems to learn Haskell and I find a recurring theme in many of these problems where I need to find a value n that gives some property (usually minimum or maximum) to a function fn . 我正在使用Euler项目问题​​来学习Haskell,并且在许多此类问题中找到了一个重复出现的主题,在这些问题中,我需要找到一个值n ,该值赋予函数fn一些属性(通常为最小值或最大值)。 As I build up a solution, I often find it convenient to create a list of pairs (n, fn) . 在构建解决方案时,我常常发现创建对(n, fn)的列表很方便。 This helps me quickly see if I have any errors in my logic because I can check against the examples given in the problem statement. 这可以帮助我快速查看逻辑上是否有任何错误,因为我可以对照问题说明中给出的示例进行检查。 Then I "filter" out the single pair that gives the solution. 然后,我“过滤”出给出解决方案的一对。 My solution to problem 47 is an example: 我对问题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..]

It seems to me that there's a more "haskelly" way to do this. 在我看来,还有一种更“轻松”的方式来执行此操作。 Is there? 在那儿?

Use maximumBy from Data.List with comparing from Data.Ord , eg 使用maximumByData.List具有comparingData.Ord ,如

maximumBy (comparing snd) [(n, f n) | n <- ns]

this will compute f once for each n . 这将为每个n计算一次f If f is cheap to compute, you can go with the simpler 如果f计算便宜,那么您可以选择更简单的方法

maximumBy (comparing f) ns

Well, you could write your function as 好吧,您可以将函数编写为

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

You could consider it "more Haskelly" to use Control.Arrow 's (&&&) , or "fan-out" 您可以认为使用Control.Arrow(&&&)或“扇出”效果“更令人讨厌”

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

To be able to tweak the code to try the simple examples first, you'd usually make it a function, abstracting over the variable(s) of interest, like so: 为了能够调整代码以首先尝试简单的示例,通常需要使它成为一个函数,对感兴趣的变量进行抽象化,如下所示:

test n m = [ x | x <- [1..], all (==n) $ map (length.primeDivisors) [x..x+m-1]]

to search for m consequitive numbers each having n distinct prime factors. 搜索每个具有n不同素数的m对数。 There is actually no need to carry the factorizations along in the final code. 实际上,最终代码中没有必要进行分解。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM