피보나치 합계로 숫자 쓰기


9

피보나치 수열을

F(1) = 1

F(2) = 2

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

그래서 우리는 무한한 순서를가집니다 1,2,3,5,8,13,... 양의 정수는 피보나치 수의 합으로 쓰여질 수 있습니다. 유일한주의 사항은이 요약이 고유하지 않을 수 있다는 것입니다. 피보나치 수의 합계로 숫자를 작성하는 방법은 항상 하나 이상 있지만 더 많은 숫자가있을 수 있습니다.

당신의 도전은 stdin을 사용하여 백만에서 백만 사이의 양의 정수를 취한 다음 stdout을 사용하여 입력에 이르는 피보나치 수의 가능한 모든 합계를 출력하는 완전한 프로그램을 작성하는 것입니다. 요약하면 피보나치 수는 반복해서는 안되며 숫자가 포함됩니다 1. 어떤 합계에서, 1존재하는 경우 위의 시퀀스 정의에서 한 번만 나타나기 때문에 한 번만 존재해야합니다 1. 용어가있는 요약은 유효하므로 입력 번호가 피보나치 번호 자체 인 경우 숫자 자체는 유효한 합계이므로 인쇄해야합니다. 여러 개의 합계 인 경우 두 합계 사이에 빈 줄이 있어야 쉽게 구분할 수 있습니다.

다음은 몇 가지 샘플입니다.

./myfib 1
1

그러한 합계는 하나 뿐이며 용어 만 있으므로 인쇄됩니다.

./myfib 2
2

여기서는 반복 1+1되므로 유효한 합계가 아닙니다 1.

./myfib 3
1+2

3

두 개의 합계와 둘 사이에 빈 줄이 인쇄됩니다.

./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하지 않습니다 ... 난 그냥이 bruteforce거야
손잡이

가장 빠른 코드가 아닌 코드 골프입니다. :-D
Fixed Point

1
나는 그것을 썼고 실제로 빨리 달린다 : P
Doorknob


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

루비, 118114 (배열 출력) 또는 138134 (정확한 출력)

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)하지만 한 문자.

올바른 출력으로 :

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

마지막 것 (12804)은 약 3 초 밖에 걸리지 않았습니다!


4

매스 매 티카, 89 85 자

David Carraher 덕분에 85 자로 줄었습니다.

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

Mathematica에는 내장 함수 Fibonacci가 있지만 사용하고 싶지 않습니다.


매우 컴팩트합니다. 좋은.
Dr. belisarius

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

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

여분의 공백을 모두 제거하십시오. 하나의 탭 또는 공백 문자를 사용하여 코드를 들여 쓸 수 있습니다. 가능하면 루프 코드를 한 줄로 작성하는 것도 더 짧습니다.while i<1000000:v+=[i];i,j=j,i+j
Wasi

몇 가지 제안 (단지 답변을 표절하고 단축 버전을 게시하고 싶지는 않았습니다) : import itertools as z 콜론 y=input()다음에 x,y,v줄 바꿈을 제거 하고 줄을 입력하고 마지막 if문장 뒤에 여분의 공간을 제거하십시오 .
SimonT

코드에 제안을 포함 시켰습니다. Thanks :)
batman

2

스칼라, 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()));}
}

이 메소드 BIEnumerable전체 (무한) 피보나치 세트를 나타내는를 반환합니다 . 숫자가 주어진 두 번째 방법 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↑⍵}: 마지막 두 요소의 합계를 목록에 추가합니다.
  • ⍣{I<⊃⌽⍺}:까지 I 목록의 마지막 요소보다 작습니다.
  • F←:에 저장합니다 F(이것은 피보나치 수에서 1~까지 I).
  • N←⍴F:에 피보나치 수를 저장하십시오 N.
  • ↓⍉(N⍴2)⊤⍳2*N:에서 숫자를 얻을 12^N비트로.
  • S←/∘F¨: 이들 각각을 비트 마스크로 사용하여 F저장하십시오 S.
  • I=+/¨S:의 각 하위 목록에 S대해 합이 같은지 확인하십시오 I.
  • S/⍨:에서 선택하십시오 S. (이제 모든 피보나치 수 목록이 I있습니다.)
  • {... : 이들 각각에 대해 :
    • ,'+',⍪⍵: +각 숫자 앞에를 추가하고
    • 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+"를 추가하고 부정함으로써 하나의 문자를 절약 할 수있었습니다.

이전 솔루션을 골프화하려고 시도하면서 다른 버전 (길이 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.