私は問題を解決しようとしている:なぜこの再帰は遅いのですか?
だけ1C、5C、10C、25C、50Cまたはコインを使用して$ 50を得るためにそこにあるどのように多くの方法?
ここに私のコードです:
main = print $ coinCombinations [1,5,10,25,50] !! 5000
coinCombinations coins = foldr recurse (1 : repeat 0) coins
where recurse a xs = take a xs ++ zipWith (+) (drop a xs) (recurse a xs)
それは多分次の時間か悪いか、私のrecurse
機能が遅いことが判明しました。しかし、私はそれが
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
ちょうどこれを推測することは、あなたの再帰のすべてのステップでテイクアンドドロップを使用することとたくさん関係しています。これらは "O(a)"関数で、おそらくsplitAtを試してみるのが良い選択でしょうか?また、++は "O(a)"演算でもあります。連結演算はポインタ演算を使用するのではなく、構造全体を走査することによって行われます。 –
私はそれが可能かもしれないと思ったが、単純な 'recurseone xs = head xs:zipWith(+)(tail xs)(recurseone xs)'を試したが、まだ遅かった。 – zoko
あなたのコードが最初の場所?しばしば、正しさの証明(正当性プロパティの「終了」部分)からリソースの使用量(つまり、複雑さの限界)を推測することができます。 – d8d0d65b3f7cf42