フィボナッチサムとして数値を書き込む


9

フィボナッチ数列を次のように定義してみましょう

F(1) = 1

F(2) = 2

F(n) = F(n - 2) + F(n - 1)

したがって、無限シーケンスがあり1,2,3,5,8,13,ます...正の整数はフィボナッチ数列の合計として記述できることはよく知られています。唯一の注意点は、この合計が一意ではない可能性があることです。フィボナッチ数の合計として数を書く方法は常に少なくとも1つありますが、もっと多くの方法があるかもしれません。

あなたの課題は、stdinを使用して100万から100万までの正の整数を取り込み、入力に加算されるフィボナッチ数のすべての可能な合計をstdoutを使用して出力する完全なプログラムを作成することです。まとめると、フィボナッチ数列は繰り返さないでください1。これには、その数が含まれます。要約すると、1存在する場合、上記のシーケンスの私の定義では1回しか1出現しないため、1回だけ存在する必要があります。項のみの合計が有効であるため、入力数値がフィボナッチ数自体である場合、数値自体は有効な合計であり、出力する必要があります。複数の合計の場合、2つの合計の間には、それらを簡単に区別するための空白行が必要です。

ここにいくつかのサンプルがあります。

./myfib 1
1

そのような合計は1つしかなく、期間も含まれているため、出力されるのはそれだけです。

./myfib 2
2

繰り返します1+1ので、これは有効な合計ではないことに注意してください1

./myfib 3
1+2

3

2つの合計とその両方は、間に空白行を入れて印刷されます。

./myfib 10
2+8

2+3+5

./myfib 100
3+8+89

1+2+8+89

3+8+34+55

1+2+3+5+89

1+2+8+34+55

3+8+13+21+55

1+2+3+5+34+55

1+2+8+13+21+55

1+2+3+5+13+21+55

真のコードゴルフ。どの言語でも最短のコードが優先されます。いくつかのテストケース(上記で示したもの以外)をコードに投稿してください。引き分けの場合は、少なくとも2週間、おそらくそれ以上待ってから、賛成票が最も高いものを選びます。だからコミュニティはあなたが好きな解決策を自由に賛成投票してください。コードの賢さ/美しさは、誰が最初に投稿するかよりも重要です。

幸せなコーディング!


1
...私はこれを総当たりにするつもりです:P私が回答を投稿した場合、それがうまく機能するとは期待しないでください:)
ドアノブ

まあそれは最速のコードではなくコードゴルフです。:-D
固定小数点

1
私はそれを書いた、そしてそれは実際に速く走る:P
Doorknob

なく、かなり重複しますが、密接に関連しcodegolf.stackexchange.com/q/2677/194
ピーター・テイラー

1
@shiona明記していないので、お好きなものを選んでください。:-)
固定小数点

回答:


9

GolfScript、54文字

~1.{3$)<}{.@+}/<[[]]{{+}+1$%+}@/\{~)+{+}*!}+,{'+'*n.}/

オンラインでテストするか、例を見てください。

> 54
2+5+13+34

> 55
1+2+5+13+34

3+5+13+34

8+13+34

21+34

55

4

Ruby、118 114(配列出力)または138 134(正しい出力)

i=gets.to_i
a=[x=y=1]
a+=[y=x+x=y]until y>i
p (1..a.size).flat_map{|n|a.combination(n).select{|o|o.inject(:+)==i}}

サンプルの実行:

c:\a\ruby>fibadd
100
[[3, 8, 89], [1, 2, 8, 89], [3, 8, 34, 55], [1, 2, 3, 5, 89], [1, 2, 8, 34, 55], [3, 8, 13, 21, 55], [1, 2, 3, 5, 34, 55], [1, 2, 8, 13, 21, 55], [1, 2, 3, 5, 13, 21, 55]]

変更getsへの$*[0]コマンドライン引数(必要な場合>fibadd 100)、1文字けれども。

正しい出力:

i=gets.to_i
a=[x=y=1]
a+=[y=x+x=y]until y>i
$><<(1..a.size).flat_map{|n|a.combination(n).select{|o|o.inject(:+)==i}}.map{|o|o*?+}*'

'

サンプルの実行:

c:\a\ruby>fibadd
100
3+8+89

1+2+8+89

3+8+34+55

1+2+3+5+89

1+2+8+34+55

3+8+13+21+55

1+2+3+5+34+55

1+2+8+13+21+55

1+2+3+5+13+21+55
c:\a\ruby>fibadd
1000
13+987

5+8+987

13+377+610

2+3+8+987

5+8+377+610

13+144+233+610

2+3+8+377+610

5+8+144+233+610

13+55+89+233+610

2+3+8+144+233+610

5+8+55+89+233+610

13+21+34+89+233+610

2+3+8+55+89+233+610

5+8+21+34+89+233+610

2+3+8+21+34+89+233+610
c:\a\ruby>obfcaps
12804
2+5+21+233+1597+10946

2+5+8+13+233+1597+10946

2+5+21+89+144+1597+10946

2+5+21+233+610+987+10946

2+5+21+233+1597+4181+6765

2+5+8+13+89+144+1597+10946

2+5+8+13+233+610+987+10946

2+5+8+13+233+1597+4181+6765

2+5+21+34+55+144+1597+10946

2+5+21+89+144+610+987+10946

2+5+21+89+144+1597+4181+6765

2+5+21+233+610+987+4181+6765

2+5+8+13+34+55+144+1597+10946

2+5+8+13+89+144+610+987+10946

2+5+8+13+89+144+1597+4181+6765

2+5+8+13+233+610+987+4181+6765

2+5+21+34+55+144+610+987+10946

2+5+21+34+55+144+1597+4181+6765

2+5+21+89+144+233+377+987+10946

2+5+21+89+144+610+987+4181+6765

2+5+21+233+610+987+1597+2584+6765

2+5+8+13+34+55+144+610+987+10946

2+5+8+13+34+55+144+1597+4181+6765

2+5+8+13+89+144+233+377+987+10946

2+5+8+13+89+144+610+987+4181+6765

2+5+8+13+233+610+987+1597+2584+6765

2+5+21+34+55+144+233+377+987+10946

2+5+21+34+55+144+610+987+4181+6765

2+5+21+89+144+233+377+987+4181+6765

2+5+21+89+144+610+987+1597+2584+6765

2+5+8+13+34+55+144+233+377+987+10946

2+5+8+13+34+55+144+610+987+4181+6765

2+5+8+13+89+144+233+377+987+4181+6765

2+5+8+13+89+144+610+987+1597+2584+6765

2+5+21+34+55+144+233+377+987+4181+6765

2+5+21+34+55+144+610+987+1597+2584+6765

2+5+21+89+144+233+377+987+1597+2584+6765

2+5+8+13+34+55+144+233+377+987+4181+6765

2+5+8+13+34+55+144+610+987+1597+2584+6765

2+5+8+13+89+144+233+377+987+1597+2584+6765

2+5+21+34+55+144+233+377+987+1597+2584+6765

2+5+8+13+34+55+144+233+377+987+1597+2584+6765

最後の1つ(12804)は約3秒しかかかりませんでした!


4

Mathematica、89 85文字

David Carraherのおかげで85文字に短縮されました。

i=Input[];#~Row~"+"&/@Select[If[#>i,Subsets@{##},#0[#+#2,##]]&[2,1],Tr@#==i&]//Column

Mathematicaには組み込みの関数Fibonacciがありますが、それを使いたくありません。


とてもコンパクト。いいね。
belisarius博士、13

1
合計のリストとして印刷しても構わない場合は、76文字:i = Input[]; #~Row~"+" & /@ Select[If[# > i, Subsets@{##}, #0[# + #2, ##]] &[2, 1], Tr@# == i &]
DavidC

1
84文字:i = Input[]; #~Row~"+" & /@ Select[If[# > i, Subsets@{##}, #0[# + #2, ##]] &[2, 1], Tr@# == i &] // Column
DavidC 2013

2

パイソン 206 181文字

import itertools as a
i,j,v,y=1,2,[],input()
while i<1000000:v,i,j=v+[i],j,i+j
for t in range(len(v)+1):
 for s in a.combinations(v,t):
  if sum(s)==y:print "+".join(map(str,s))+"\n"

サンプル実行:

25
1+3+21

1+3+8+13

1000
13+987

5+8+987

13+377+610

2+3+8+987

5+8+377+610

13+144+233+610

2+3+8+377+610

5+8+144+233+610

13+55+89+233+610

2+3+8+144+233+610

5+8+55+89+233+610

13+21+34+89+233+610

2+3+8+55+89+233+610

5+8+21+34+89+233+610

2+3+8+21+34+89+233+610

これらの余分なスペースをすべて削除します。1つのタブまたはスペース文字を使用して、コードをインデントできます。また、可能な場合はループコードを1行で書く方が短いですwhile i<1000000:v+=[i];i,j=j,i+j
Wasi

いくつかの提案(私は単にあなたの答えを盗用し、私の短縮版を投稿したくありませんでした)import itertools as z:、コロンの後の改行を削除y=input()し、x,y,v行と一緒に挿入し、最後のifステートメントの後の余分なスペースを削除します。
SimonT 2013

私はあなたの提案をコードに含めました。ありがとう:)
バットマン

2

Scala、171

def f(h:Int,n:Int):Stream[Int]=h#::f(n,h+n)
val x=readInt;(1 to x).flatMap(y=>f(1,2).takeWhile(_<=x).combinations(y).filter(_.sum==x)).foreach(z=>println(z.mkString("+")))

2

C#、376バイト

class A{IEnumerable<int>B(int a,int b){yield return a+b;foreach(var c in B(b,a+b))yield return c;}void C(int n){foreach(var j in B(0,1).Take(n).Aggregate(new[]{Enumerable.Empty<int>()}.AsEnumerable(),(a,b)=>a.Concat(a.Select(x=>x.Concat(new[]b})))).Where(s=>s.Sum()==n))Console.WriteLine(string.Join("+",j));}static void Main(){new A().C(int.Parse(Console.ReadLine()));}}

非ゴルフ:

class A
{
    IEnumerable<int>B(int a,int b){yield return a+b;foreach(var c in B(b,a+b))yield return c;}
    void C(int n){foreach(var j in B(0,1).Take(n).Aggregate(new[]{Enumerable.Empty<int>()}.AsEnumerable(),(a,b)=>a.Concat(a.Select(x=>x.Concat(new[]{b})))).Where(s=>s.Sum()==n))Console.WriteLine(string.Join("+",j));}
    static void Main(){new A().C(int.Parse(Console.ReadLine()));}
}

このメソッドBは、IEnumerable(無限の)フィボナッチセット全体を表すを返します。2番目のメソッドは、数値を指定nして、最初のnフィボナッチ数(ここでは巨大な過剰)を調べ、すべての可能なサブセット(べき集合)を見つけ、合計が正確にnであるサブセットにフィルターして、出力します。


1

APL(75)

I←⎕⋄{⎕←⎕TC[2],1↓,'+',⍪⍵}¨S/⍨I=+/¨S←/∘F¨↓⍉(N⍴2)⊤⍳2*N←⍴F←{⍵,+/¯2↑⍵}⍣{I<⊃⌽⍺}⍳2

主に出力形式のため、私が望んでいるよりも競争力が低い。

出力:

⎕:
      100

 3 + 8 + 89 

 3 + 8 + 34 + 55 

 3 + 8 + 13 + 21 + 55 

 1 + 2 + 8 + 89 

 1 + 2 + 8 + 34 + 55 

 1 + 2 + 8 + 13 + 21 + 55 

 1 + 2 + 3 + 5 + 89 

 1 + 2 + 3 + 5 + 34 + 55 

 1 + 2 + 3 + 5 + 13 + 21 + 55 

説明:

  • I←⎕:入力を読み取り、に格納しIます。
  • ⍳2:リストから始めて1 2
  • {⍵,+/¯2↑⍵}:最後の2つの要素の合計をリストに追加します。
  • ⍣{I<⊃⌽⍺}:until Iがリストの最後の要素より小さいです。
  • F←:に格納しますF(これらはから1までのフィボナッチ数Iです)。
  • N←⍴F:フィボナッチ数をに保存しNます。
  • ↓⍉(N⍴2)⊤⍳2*N:から1までの数2^Nをビットとして取得します。
  • S←/∘F¨:これらのそれぞれをビットマスクとして使用しF、に格納しSます。
  • I=+/¨S:の各サブリストSについて、その合計がに等しいかどうかを確認しIます。
  • S/⍨:これらから選択しますS。(これで、合計がになるフィボナッチ数のすべてのリストがありますI。)
  • {...:これらのそれぞれについて:
    • ,'+',⍪⍵+各番号の前にa を追加し、
    • 1↓:最初の+バックオフ、
    • ⎕TC[2]:余分な改行を追加します。
    • ⎕←:および出力。

1

ハスケル-127

多くの繰り返しの後、私は次のコードで終わりました:

f=1:scanl(+)2f
main=getLine>>=putStr.a f "".read
a(f:g)s n|n==f=s++show f++"\n\n"|n<f=""|n>f=a g(s++show f++"+")(n-f)++a g s n

すべての出力行の前に「0+」をだまして追加することで、おそらく1文字を節約できたでしょう。

以前の解決策を試している間に思いついた別のバージョン(長さ143)を共有したいと思います。これまでに、演算子とタプルを乱用したことはありません。

f=1:scanl(+)2f
main=getLine>>=(\x->putStr$f€("",read x))
o%p=o++show p;(f:g)€t@(s,n)|n==f=s%f++"\n\n"|n<f=""|n>f=g€(s%f++"+",n-f)++g€t

テストケース、256:

256
2+3+5+13+34+55+144

2+3+5+13+89+144

2+3+5+13+233

2+8+13+34+55+144

2+8+13+89+144

2+8+13+233

2+21+34+55+144

2+21+89+144

2+21+233

と1000:

1000
2+3+8+21+34+89+233+610

2+3+8+55+89+233+610

2+3+8+144+233+610

2+3+8+377+610

2+3+8+987

5+8+21+34+89+233+610

5+8+55+89+233+610

5+8+144+233+610

5+8+377+610

5+8+987

13+21+34+89+233+610

13+55+89+233+610

13+144+233+610

13+377+610

13+987

誰かがこれを持っていたので、いくつかの効率データ:

% echo "12804" | time ./fibsum-golf > /dev/null
./fibsum-golf > /dev/null  0.09s user 0.00s system 96% cpu 0.100 total
% echo "128040" | time ./fibsum-golf > /dev/null
./fibsum-golf > /dev/null  2.60s user 0.01s system 99% cpu 2.609 total

0

05AB1E、19バイト(非競合)

ÅFævy©O¹Qi®'+ý}})ê»

オンラインでお試しください!

任意ののすべての可能な合計を計算しますn。1000の出力例:

1+1+3+8+144+233+610
1+1+3+8+21+34+89+233+610
1+1+3+8+377+610
1+1+3+8+55+89+233+610
1+1+3+8+987
13+144+233+610
13+21+34+89+233+610
13+377+610
13+55+89+233+610
13+987
2+3+8+144+233+610
2+3+8+21+34+89+233+610
2+3+8+377+610
2+3+8+55+89+233+610
2+3+8+987
5+8+144+233+610
5+8+21+34+89+233+610
5+8+377+610
5+8+55+89+233+610
5+8+987
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.