2009-03-16 18 views
0

免責事項:私はHaskellを初めて使い、大学のFPについて多くのことを覚えていないので、コードに1つ以上のエラーがあるかもしれません。これは、オイラー問題3のコードです。Haskell:配列引数の再帰

私は、引数として2つの配列を持つ関数と結果として配列を再帰的に呼び出そうとしています。

目標:

  • は、nと仮定
  • (変数は「allNumbers」のコードである)1からnまでの全ての自然数のリストを、この質問のための10
  • 作成されるの別のリストを作成します1からnまでのすべての自然数(変数は 'allFactors'はコード)
  • 'allFactors'の最初の要素を取り、 'allFactors'の残りの数にこの数を掛けます。
  • これらの数字を 'allNumbers'からすべて削除します。
  • 'allFactors'が空になるまで1からnまで続きます。

    mkList :: Int -> [Int] 
    mkList n = [1..n-1] 
    
    modArray :: Int -> Int -> [Int] 
    modArray a b = [ x*b | x <- [1..a], x `mod` b == 0] 
    
    modArrayAll :: [Int] -> [Int] -> [Int] 
    modArrayAll [] [] = [] 
    modArrayAll (x:xs) (y:ys) = (e) 
        where 
         m = head(ys) 
         n = length(xs) 
         e = (modArrayAll xs ys) \\ modArray n m 
    

    (メインで)これは空リストになり

    let allNumbers = mkList (first + 1) 
    let allFactors = mkList (first + 1) 
    let mainList2 = modArrayAll allNumbers allFactors 
    

は、ここに私のコードです。しかし、もし私が持っている:私は10

私の質問への1からすべての奇数番号を取得

e = xs \\ modArray n m --WORKS for one iteration 

:なぜこれが道を働いていない私はそれを期待しますか?再帰スタックは空の配列条件を打ち、呼び出し配列から削除されない空の配列を返すだけで、素数だけを返すことになるでしょうか?

答えて

5

私はあなたの目標のノートをコピー:

-- assume n is 10 for this question 
n=10 

-- create a list of all natural numbers from 1 to n (variable is 'allNumbers' is code) 
allNumbers = [1..n] 

-- create another list of all natural numbers from 1 to n (variable is 'allFactors' is code) 
allFactors = [2..n] -- i suspect you really wanted this rather than [1..n] 

-- take the first element in 'allFactors' and 
-- multiply the rest of the numbers of 'allFactors' by this number. 
-- (this generates an array of numbers) 
-- continue from 1 to n until 'allFactors' is empty 
factorProducts = [ x*y | x <- allFactors, y <- allFactors] 

-- remove all these numbers from 'allNumbers' 
whatYouWanted = allNumbers \\ factorProducts 

あなたはまだかなり不可欠考え方で考えているように見える瞬間。どのようにそれを得るかではなく、あなたが望むものについてもっと考えてみてください:)

+0

フィードバックありがとうございます。私が望むのは、すべて「n」の素因です。私はPythonで別のアルゴリズムを試しました。だから、私はhaskellでそのことをどうやって行うのかについては完全には分かっていません(それはしばらくありました) – cbrulak

+0

フィードバックに感謝します。私は自分のコードを書き直して、それが良いと思います。 – cbrulak

1

modArray n mは、整数の「メインリスト」から削除するmの倍数のリストを作成します。しかしmodArray n mには1*mが含まれているため、各番号はそれ自身の「複数」であるため削除されます。あなたのテストケースでは結果として奇数しか得られませんが、2を依然として結果リストに入れたいと思うでしょう。さらに、すべての数値が1の倍数であるため、すべての数値が除外されます。

再帰の終了のケースはmodArrayAll [] [] = []なので、空のリストが返されます。そして、周囲の再帰呼び出しでこの戻り値は、ここで使用されます。

(modArrayAll xs ys) \\ modArray n m 

これはmodArrayAll xs ysによって返さすでに空のリストから他の要素(modArray n mによって返されたもの)を削除しようとします。新しい要素はどこにも追加されず、結果リストは空のままです。あなたのアルゴリズムでは、[] -caseが空の数字ではなく、数字のリスト全体を返すようにします。周囲の再帰関数呼び出し内の\\ modArray n mは、非プライム要因をますます除外することができます。