Zdefiniujmy sekwencję Fibonacciego jako
F(1) = 1
F(2) = 2
F(n) = F(n - 2) + F(n - 1)
Mamy więc nieskończoną sekwencję 1,2,3,5,8,13,
... Dobrze wiadomo, że każdą dodatnią liczbę całkowitą można zapisać jako sumę niektórych liczb Fibonacciego. Jedynym zastrzeżeniem jest to, że to podsumowanie może nie być wyjątkowe. Zawsze istnieje co najmniej jeden sposób na zapisanie liczby jako sumy liczb Fibonacciego, ale może być ich znacznie więcej.
Twoim wyzwaniem jest napisanie kompletnego programu, który za pomocą stdin przyjmuje dodatnią liczbę całkowitą od jednego do miliona włącznie, a następnie wypisuje za pomocą stdout wszystkie możliwe sumy liczb Fibonacciego, które sumują się do danych wejściowych. Podsumowując, liczby Fibonacciego nie mogą się powtarzać i obejmuje to liczbę 1
. W każdym podsumowaniu, jeśli 1
jest obecne, musi być obecne tylko raz, ponieważ w mojej definicji powyższej sekwencji 1
pojawia się tylko raz. Sumy z tylko terminem są poprawne, więc jeśli liczbą wejściową jest sama liczba Fibonacciego, to sama liczba jest poprawną sumą i musi zostać wydrukowana. W przypadku wielu sum, pomiędzy dowolnymi dwoma sumami musi znajdować się pusty wiersz, aby łatwo je rozróżnić.
Oto kilka próbek.
./myfib 1
1
Jest tylko jedna taka suma i ma ona tylko termin, więc to wszystko, co jest drukowane.
./myfib 2
2
Zauważ, że 1+1
nie jest to poprawna suma, ponieważ się 1
powtarza.
./myfib 3
1+2
3
Dwie kwoty i obie są wydrukowane z pustą linią pomiędzy nimi.
./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
Prawdziwy golf. Wygrywa najkrótszy kod w dowolnym języku. Proszę zamieścić kod wraz z niektórymi przypadkami testowymi (oprócz tego, który podałem powyżej). W przypadku remisów wybieram ten z najwyższymi ocenami po odczekaniu co najmniej dwóch tygodni i prawdopodobnie dłużej. Społeczność może więc głosować za rozwiązaniami, które lubisz. Sprytność / piękno kodu ma o wiele większe znaczenie niż to, kto pierwszy.
Miłego kodowania!
Odpowiedzi:
GolfScript, 54 znaki
Przetestuj online lub spójrz na przykłady:
źródło
Ruby,
118114(wyjście z tablicy) lub138134 (prawidłowe wyjście)Przykładowy przebieg:
Zmień
gets
na,$*[0]
jeśli chcesz argumenty wiersza poleceń (>fibadd 100
), ale znak +1.Przy prawidłowym wyjściu:
Przykładowe przebiegi:
Ten ostatni (12804) zajął tylko około 3 sekundy!
źródło
Mathematica,
8985 znakówSkrócony do 85 znaków dzięki Davidowi Carraherowi.
Mathematica ma wbudowaną funkcję
Fibonacci
, ale nie chcę jej używać.źródło
i = Input[]; #~Row~"+" & /@ Select[If[# > i, Subsets@{##}, #0[# + #2, ##]] &[2, 1], Tr@# == i &]
i = Input[]; #~Row~"+" & /@ Select[If[# > i, Subsets@{##}, #0[# + #2, ##]] &[2, 1], Tr@# == i &] // Column
Pyton
206181 znakówPrzykładowy przebieg:
źródło
while i<1000000:v+=[i];i,j=j,i+j
import itertools as z
usuń znaki nowej linii po dwukropkach, wstaw linięy=input()
wraz zx,y,v
linią i usuń dodatkowe miejsce po końcowymif
stwierdzeniu.Scala, 171
źródło
C #, 376 bajtów
Nie golfowany:
Metoda
B
zwraca anIEnumerable
reprezentujący cały (nieskończony) zbiór Fibonacciego. Druga metoda, biorąc pod uwagę liczbęn
, sprawdza pierwszen
liczby Fibonacciego (tutaj ogromna nadwyżka mocy), znajduje wszystkie możliwe podzbiory (zestaw mocy), a następnie filtruje do podzbiorów, których suma jest dokładnien
, a następnie drukuje.źródło
APL (75)
Mniej konkurencyjny, niż bym chciał, głównie ze względu na format wyjściowy.
Wynik:
Wyjaśnienie:
I←⎕
: odczytać wejście, zapisać wI
.⍳2
: zaczynając od listy1 2
,{⍵,+/¯2↑⍵}
: dodaj sumę dwóch ostatnich elementów do listy,⍣{I<⊃⌽⍺}
: dopókiI
jest mniejszy niż ostatni element listy.F←
: zapisz wF
(są to liczby Fibonacciego od1
doI
).N←⍴F
: zapisz liczbę liczb Fibonacciego wN
.↓⍉(N⍴2)⊤⍳2*N
: uzyskaj liczby od1
do2^N
, jako bity.S←/∘F¨
: użyj każdego z nich jako maski bitowejF
, zapisz wS
.I=+/¨S
: dla każdej podlisty wS
sprawdź, czy jej suma jest równaI
.S/⍨
: wybierz je zS
. (Teraz mamy wszystkie listy liczb Fibonacciego, które się sumująI
.){
...}¨
: dla każdego z tych:,'+',⍪⍵
: dodaj+
przed każdym numerem,1↓
: zdejmij pierwszy+
,⎕TC[2]
: dodaj dodatkową linię,⎕←
: i wyjście.źródło
Haskell - 127
Po wielu iteracjach otrzymałem następujący kod:
Mógłbym uratować może jedną postać, oszukując i dodając dodatkowe „0+” przed każdą linią wyjściową.
Chcę udostępnić inną wersję (długość 143), którą wymyśliłem, próbując zagrać w golfa w poprzednim rozwiązaniu. Nigdy wcześniej nie nadużywałem operatorów i krotek tak często:
Przypadki testowe, 256:
i 1000:
Niektóre dane dotyczące wydajności, ponieważ ktoś miał te rzeczy:
źródło
05AB1E , 19 bajtów ( niekonkurencyjny )
Wypróbuj online!
Oblicza wszystkie możliwe sumy dla danego
n
. Przykładowe dane wyjściowe dla 1000:źródło