2017-11-08 10 views
3

ハスケルでMersenne numberを表示する簡単な再帰関数を作成する作業があります。最小のものから最大のものにソートされています。 そうmersenne 7 basicly 2^n-1の のは、我々はそれが悲しげに成し遂げることができませんでしたし、コードのその部分に貼付されていること[0,1,3, 7, 15, 31, 63]Haskellでのメルセンヌ数の計算

ようになります。

mrs :: Integer -> [Integer] 
mrs 1 = [0] 
mrs n = n : mrs (2^(n-1)-1) 

しかし、nが低くなっているので、彼らは減少するはずである一方で何とか数字のサイズが増加しています。私はそれが解決するのは簡単だと思うし、後で気分が落ちるだろうが、そうだ。 [3,3,3,3...]、それはnegativ指数について私に告げるよりも低い:

は現在、入力7のために、それは常に3年代を吐く入力3について[7, 63, 46.........giant number, error]

を出してくれる。

ハスケルにとっては新しく、スクリプトを使ったグーグルと読書はうまくいきませんでした。

+0

をあなたはそれを減少していない、あなたの数nを毎回増加しています。 '2 ^(n-1)-1'は、各呼び出し時に関数に渡す新しい' n'値です。 – jkeuhlen

+2

数字は減少していません。あなたは2 ^(n-1)-1でmrsを呼び出しています。リストに入れる数字と計算する数字を逆にしたようです。 – Axnyff

+1

'mrs n 'を呼び出すと、' n'は何を表しているのでしょうか? –

答えて

4

コールごとにnの値を減らす必要がありますが、現在は増加しています。あなたが本当にしたいことはおそらくです:

mrs :: Integer -> [Integer] 
mrs 1 = [0] 
mrs n = (2^(n-1)-1) : mrs (n-1) 

> mrs 7 
[63,31,15,7,3,1,0] 

あなたは昇順を維持したい場合は、単にリストリバース:

> reverse $ mrs 7 
[0,1,3,7,15,31,63] 
+1

おそらく 'n> 1'のガードを追加する価値があります。それ以外の場合は' mrs 0'は無限リストになります。 –

+0

@WillemVanOnsemフェアポイント。私はメルセンヌの数字が正のnだけで定義されていると思っていましたが、その保護なしでは危険な機能を残しています。 – jkeuhlen

+0

ありがとう、私は "ちょっと"離れていることを知っていました。今私はそれについて考える、それは本当にストレートです。リストの最初の要素は私のステートメントで、テールは-1になるまで再帰的になります。まだ構文に慣れています。とにかく、ありがとうございます! –

1

これを行うにはより宣言スタイルはおそらく範囲を定義している[1..n]、その後、その上にマッピングを行う:\x -> 2^(x-1)-1

mrs n = map (\x -> 2^(x-1)-1) [1..n] 

またはpointfreeアプローチ:

mrs n = map (subtract 1 . (2 ^) . subtract 1) [1..n] 

今、私たちは、範囲内に既にsubtract 1を行うことで、状況を改善することができます

mrs n = map (subtract 1 . (2 ^)) [0..n-1]

はこれが生成します。

Prelude> mrs 7 
[0,1,3,7,15,31,63] 
+0

オリジナルの質問はすでにそれらを増やしたい* – luqui

+0

@luqui:頭のおかげで:) –