1

n私は Project Euler の問題を使用して Haskell を学習していますが、これらの問題の多くで、 function に何らかのプロパティ (通常は最小または最大) を与える値を見つける必要があるという繰り返しのテーマを見つけましたf n。解決策を構築するとき、ペアのリストを作成すると便利であることがよくあります(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..]

これを行うには、もっと「ハスケリー」な方法があるように思えます。ある?

4

2 に答える 2

6

maximumByfromData.Listと一緒にcomparingfromData.Ordを使用します。

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

fこれはごとに 1 回計算されますnf計算が安価な場合は、より単純なものを使用できます

maximumBy (comparing f) ns
于 2012-09-05T02:14:38.193 に答える
0

さて、あなたはあなたの関数を次のように書くことができます

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

Control.Arrow(&&&)、または「ファンアウト」を使用することを「より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それぞれがn異なる素因数を持つ連続数を検索します。実際には、最終的なコードで因数分解を実行する必要はありません。

于 2012-09-05T14:27:31.043 に答える