Twoje zadanie:
Napisz program lub funkcję, aby sprawdzić, czy wprowadzona liczba jest liczbą Fibonacciego . Liczba Fibonacciego to liczba zawarta w sekwencji Fibonacciego.
Sekwencja Fibonacciego jest zdefiniowana jako:
F(n) = F(n - 1) + F(n - 2)
Z nasionami F(0) = 0
i F(1) = 1
.
Wejście:
Nieujemna liczba całkowita od 0 do 1 000 000 000, która może, ale nie musi być liczbą Fibonacciego.
Wynik:
Wartość true / falsy wskazująca, czy dane wejściowe są liczbą Fibonacciego.
Przykłady:
0-->truthy
1-->truthy
2-->truthy
12-->falsy
Punktacja:
To jest golf golfowy , wygrywa najmniej bajtów.
code-golf
sequence
decision-problem
fibonacci
Gryphon - Przywróć Monikę
źródło
źródło
Odpowiedzi:
Neim , 2 bajty
Wyjaśnienie:
Działa tak samo jak moja odpowiedź To Hip to Square , ale używa innej nieskończonej listy:
f
dla Fibonacciego.Spróbuj!
źródło
66 D5
JavaScript (ES6), 34 bajty
Rekurencyjnie generuje sekwencję Fibonacciego, aż znajdzie element większy lub równy wejściowi, a następnie zwraca element == wejście.
źródło
Siatkówka , 23 bajty
Wypróbuj online!
Wejście w jednostkowej, wyjściowej
0
lub1
.Wyjaśnienie
Sekwencja Fibonacciego jest dobrym kandydatem do rozwiązania z referencjami do przodu, tj. „Referencją wsteczną”, która odnosi się albo do otaczającej grupy, albo do grupy, która pojawia się później w wyrażeniu regularnym (w tym przypadku faktycznie używamy obu z nich). Przy dopasowywaniu takich liczb, musimy znaleźć wyrażenie rekurencyjne dla różnicy między elementami sekwencji. Np. Aby dopasować liczby trójkątne, zwykle dopasowujemy poprzedni segment plus jeden. Aby dopasować liczby kwadratowe (których różnicami są liczby nieparzyste), dopasowujemy poprzedni segment plus dwa.
Ponieważ liczby Fibonacciego uzyskujemy przez dodanie elementu ostatniego do ostatniego, różnice między nimi są również tylko liczbami Fibonacciego. Musimy więc dopasować każdy segment jako sumę dwóch poprzednich. Rdzeń wyrażenia regularnego jest następujący:
Teraz kończy się dodając numery Fibonacciego zaczynając od 1 , czyli 1, 1, 2, 3, 5, ... . Ci dodać do 1, 2, 4, 7, 12, ... . To znaczy, że są one o jeden mniejsze niż liczby Fibonacciego, więc dodajemy
1
na końcu. Jedynym przypadkiem, którego to nie obejmuje, jest zero, więc^$
na początku mamy alternatywę.źródło
^$|^(^1|\2?+(\1))*1$
^
.Regex (smak ECMAScript),
392358328224206165 bajtówTechniki, które muszą wejść w grę, aby dopasować liczby Fibonacciego do wyrażenia regularnego ECMAScript (jednostronnie), są dalekie od tego, jak najlepiej to zrobić w większości innych smaków wyrażeń regularnych. Brak odwołań do przodu / zagnieżdżonych wstecz lub rekurencji oznacza, że nie można bezpośrednio policzyć ani zachować bieżącej sumy czegokolwiek. Brak wyglądu sprawia, że często jest to wyzwanie, nawet mając wystarczająco dużo miejsca do pracy.
Do wielu problemów należy podchodzić z zupełnie innej perspektywy i wydają się nierozwiązywalne aż do pojawienia się jakiegoś kluczowego wglądu. Zmusza cię to do rzucenia znacznie szerszej sieci w celu znalezienia, które matematyczne właściwości liczb, z którymi pracujesz, mogą być wykorzystane do rozwiązania konkretnego problemu.
W marcu 2014 r. Stało się tak w przypadku liczb Fibonacciego. Patrząc na stronę Wikipedii, początkowo nie mogłem znaleźć sposobu, chociaż jedna konkretna właściwość wydawała się kusząco blisko. Następnie matematyk teukon nakreślił metodę, która wyraźnie dała do zrozumienia, że można to zrobić, używając tej właściwości razem z inną. Nie chciał skonstruować wyrażenia regularnego. Jego reakcja, kiedy poszedłem naprzód i to zrobiłem:
Podobnie jak w przypadku moich innych jednoargumentowych wyrażeń regularnych ECMAScript, ostrzeżę : Gorąco zalecam naukę rozwiązywania pojedynczych problemów matematycznych w wyrażeniach regularnych ECMAScript. To była dla mnie fascynująca podróż i nie chcę zepsuć jej nikomu, kto mógłby potencjalnie chcieć spróbować samemu, szczególnie tym, którzy interesują się teorią liczb. Zobacz ten post, aby uzyskać listę zalecanych problemów oznaczonych spoilerem do rozwiązania jeden po drugim.
Więc nie czytaj dalej, jeśli nie chcesz, aby zepsuła Ci się magia wyrażeń regularnych . Jeśli chcesz spróbować samodzielnie odkryć tę magię, zdecydowanie polecam zacząć od rozwiązania niektórych problemów z wyrażeniem regularnym ECMAScript, jak opisano w linku powyżej.
Wyzwanie, z którym początkowo się zmierzyłem: dodatnia liczba całkowita x jest liczbą Fibonacciego tylko wtedy, gdy 5x 2 + 4 i / lub 5x 2 - 4 to idealny kwadrat. Ale nie ma miejsca na obliczenie tego w wyrażeniu regularnym. Jedyne miejsce, w którym musimy pracować, to sam numer. Nie mamy nawet dość miejsca, aby pomnożyć przez 5 lub wziąć kwadrat, nie mówiąc już o obu.
pomysł teukona na to, jak go rozwiązać ( pierwotnie opublikowany tutaj ):
A oto makieta algorytmu w C, który napisałem jako test przed zaimplementowaniem go w regexie.
Więc bez zbędnych ceregieli, oto regex:
^((?=(x*).*(?=x{4}(x{5}(\2{5}))(?=\3*$)\4+$)(|x{4})(?=xx(x*)(\6x?))\5(x(x*))(?=(\8*)\9+$)(?=\8*$\10)\8*(?=(x\2\9+$))(x*)\12)\7\11(\6\11|\12)|x{0,3}|x{5}|x{8}|x{21})$
Wypróbuj online!
I ładnie wydrukowana, skomentowana wersja:
Algorytm mnożenia nie jest wyjaśniony w tych komentarzach, ale jest krótko wyjaśniony w akapicie mojego obfitego numeru wyrażenia regularnego .
Utrzymywałem sześć różnych wersji wyrażenia Fibonacciego: cztery, które zapadają od najkrótszej do największej prędkości i używają algorytmu wyjaśnionego powyżej, oraz dwie inne, które używają innego, znacznie szybszego, ale o wiele dłuższego algorytmu, który, jak się przekonałem, może faktycznie powrócić indeks Fibonacciego jako dopasowanie (objaśnienie tego algorytmu jest poza zakresem tego postu, ale wyjaśniono to w oryginalnej dyskusji Gist ). Nie sądzę, bym zachował tak wiele bardzo podobnych wersji wyrażenia regularnego, ponieważ w tym czasie przeprowadzałem wszystkie testy w PCRE i Perlu, ale mój silnik wyrażeń regularnych jest wystarczająco szybki, aby obawy o szybkość nie były już tak ważne (a jeśli konkretny konstrukt powoduje wąskie gardło, mogę dodać dla niego optymalizację) - choć prawdopodobnie ponownie utrzymałbym jedną najszybszą wersję i jedną najkrótszą wersję, jeśli różnica w prędkości były wystarczająco duże.
Wersja „zwraca indeks Fibonacciego minus 1 jako dopasowanie” (niezbyt mocno golfa):
Wypróbuj online!
Wszystkie wersje są na github z pełną historią zatwierdzeń optymalizacji golfa:
regex do dopasowania liczb Fibonacciego - krótkie, prędkość 0.txt (najkrótszą ale najwolniejszy jeden, jak w tym poście)
regex do dopasowania liczb Fibonacciego - krótkie, prędkość 1.txt
regex do dopasowania liczb Fibonacciego - krótki, prędkość 2.txt
regex dopasowania liczby Fibonacciego - krótki, prędkość 3.txt
regex do dopasowania liczb Fibonacciego - fastest.txt
regex do dopasowania liczb Fibonacciego - powrót index.txt
źródło
Python 3 , 48 bajtów
Wypróbuj online!
źródło
int
zwiększyłoby poprzeczkę (wciąż nie jest arbitralnie duże), ale nie zmuszamy również odpowiedzi C do korzystania z 64-bitowych liczb całkowitych (lub 128-bitowych z gcc). W każdym razie pozwolenie na użycie tego samego algorytmu w jednym języku, ale nie w innym, wydaje się nonsensowne.Python 2,
4844 bajtówWypróbuj online
Podziękowania dla Jonathana Allana za uratowanie 4 bajtów
źródło
False
prawdziwe wartości i wartości fałszTrue
: TIO!n-a
zamiastn==a
i mieć -1 i 0 jako wartości zwracane.-101
zamiast tego uzyskać inny wynik-1
.05AB1E ,
87 bajtówWyjaśnienie:
Wypróbuj online!
-1 dzięki Jonathanowi Allanowi za obejście problemu 0-nie-a-fibonacciego.
źródło
n
(oszczędzając bajt), ponieważÅF
jest to włącznie i¹å
przyniosłoby to w0
obu przypadkachn=0
?Perl 6 , 23 bajtów
źródło
{(0,1,*+*...^*>$_).tail==$_}
było to, co zamierzałem początkowo opublikować. Być może w końcu udało mi się dotrzeć do operatorów zestawów .Poważnie , 3 bajty
Wypróbuj online!
Zwraca indeks +1 na liście liczb Fibonacciego, jeśli jest prawdziwy, w przeciwnym razie zwraca fałsz.
Wyjaśnienie:
źródło
Galaretka ,
8 76 bajtówWypróbuj online!
W jaki sposób?
Uwagi:
‘
potrzebna jest więc to działa na 2 i 3 , ponieważ są to 3 rd i 4 th Liczby Fibonacciego - ponad 3 wszystkie liczby Fibonacciego są większe niż ich indeksu.-
jest potrzebna (a nie tylko‘R
), tak to działa na 0 od 0 to 0 th liczba Fibonacciego;źródło
3
:)ZX81 BASIC
180151100~ 94 tokenizowanych bajtów BASICDzięki Moggy na forach SinclairZXWorld, jest to o wiele fajniejsze rozwiązanie, które oszczędza więcej bajtów.
To da 1, jeśli wprowadzono liczbę Fibonacciego, lub zero, jeśli nie. Chociaż oszczędza to bajty, jest znacznie wolniejsze niż stare rozwiązania poniżej. Aby uzyskać szybkość (ale więcej BASIC bajtów) usuń
VAL
opakowania wokół literalnych liczb ciągu. Oto stare (er) rozwiązania z kilkoma objaśnieniami:Powyższe poprawki oszczędzają dalsze BASIC bajty do zagęszczenia
IF
instrukcji w jedenPRINT
wiersz 12; inne bajty zostały zapisane przy użyciuVAL
słowa kluczowego i przy użyciuGOTO CODE "£"
, który w zestawie znaków ZX81 ma wartość 12. Ciągi zapisują więcej bajtów nad liczbami, ponieważ wszystkie wartości liczbowe są przechowywane jako liczby zmiennoprzecinkowe, dlatego zajmują więcej miejsca na stosie VAR.źródło
5 IF R<F THEN NEXT I
- mój zły!C #, 109 bajtów
Zdecydowanie można to poprawić, ale nie miałem czasu.
źródło
n=>{int a=0,b=1,c=0;while(a<n&b<n)if(++c%2>0)a=a+b;else b=a+b;return a==n|b==n;}
(tylko 80 bajtów). Wypróbuj online!a+=b
zamiasta=a+b
ib+=a
zamiastb=a+b
.> <> ,
2119 + 3 =2422 bajtówDane wejściowe powinny znajdować się na stosie podczas uruchamiania programu, więc +3 bajty dla
-v
flagi.Wypróbuj online!
Działa to poprzez generowanie liczb Fibonacciego, aż będą większe lub równe liczbie wejściowej, a następnie sprawdzanie, czy ostatnio wygenerowana liczba jest równa z danymi wejściowymi. Wyprowadza,
1
jeśli była to liczba Fibonacciego, w0
przeciwnym razie.Aby upewnić się, że
0
jest obsługiwany poprawnie, ziarno jest-1 1
- pierwsza wygenerowana liczba będzie0
raczej niż1
.Dzięki @cole za wskazanie, którego
i
można użyć do wypchnięcia-1
na stos, gdy STDIN jest pusty. Bardzo mądry!Poprzednia wersja:
źródło
i
zamiast01-
.i
jak-1
wtedy, gdy nie ma danych wejściowych do STDIN, nie rozważyłem tego. Ładnie wykonane!Mathematica, 37 bajtów
-4 bajty z @ngenisis
źródło
Fibonacci[0]
daje0
, więc możesz oszczędzać4
bajty, włączając się0
wTable
zakres. Możesz zapisać kolejny bajt, używając notacjiTable
!Fibonacci@n~Table~{n,0,#+1}~FreeQ~#&
MATL (16 bajtów)
Wypróbuj online!
Nie jest to najbardziej golfowe rozwiązanie, ale chciałem zastosować bezpośrednią metodę sprawdzenia, czy „5 * x ^ 2 +/- 4” to idealny kwadrat .
Wyjaśnienie:
Uwaga:
W przypadku „0” zwraca „2”, ponieważ zarówno 4, jak i -4 są idealnymi kwadratami, tak samo jak 1, co daje „1 1”. Rozważ każde niezerowe wyjście jako „prawdę”, a 0 jako „fałsz”.
źródło
Pari / GP , 32 bajty
Wypróbuj online!
źródło
PHP , 44 bajty
Wypróbuj online!
PHP , 58 bajtów
Wypróbuj online!
źródło
for(;0>$s=$x-$argn;)$x=+$y+$y=$x?:1;echo!$s;
.Java,
7269686359555049 bajtówSprawdź to sam!
Alternatywa (wciąż 49 bajtów)
Niezbyt oryginalny: jest to prosta i podstawowa wersja iteracyjna.
Działa to dla liczb do 1 836 311,903 (47-ta liczba Fibonacciego) włącznie. Ponadto wynik jest niezdefiniowany (w tym potencjalna nieskończona pętla).
Podziękowania dla Kevina Cruijssena i Davida Conrada za pomoc w grze w golfa :)
źródło
n==0
nan<1
. W pytaniu jest napisane „ Nieujemna liczba całkowita od 0 do 1 000 000 000 ”.b+=a;a=b-a;
C # (.NET Core) , 51 bajtów
Wypróbuj online!
-6 bajtów dzięki @Oliver!
To rozwiązanie wykorzystuje dość prostą funkcję rekurencyjną.
n
to liczba do przetestowania.a
ib
są 2 najnowszymi liczbami w sekwencji.Łącze TIO pokazuje, że działa on dla 1134903170, który przekracza maksymalną wartość wymaganą przez wyzwanie.
źródło
a<n
dla 51 bajtówAlchemist ,
205134 bajtówOgromne podziękowania dla ASCII tylko za dość sprytne scalanie stanów, oszczędzając 71 bajtów !!
Wypróbuj online lub sprawdź partię!
Bez golfa
źródło
0
kontrole pod kątem mniejszej liczby bajtów kosztem niedeterminizmub
Błąd kończy się na 0, ale brak dodania -atomu podczas inicjalizacji naprawia go (i zapisuje 2 bajty): D DziękiGalaretka , 5 bajtów
Wypróbuj online!
Zwraca 0 dla liczb innych niż Fibonacciego, a 1-indeksowana pozycja liczby w sekwencji Fibonacciego dla liczb Fibonacciego.
Wyjaśnienie:
źródło
Dyalog APL, 17 bajtów
Wypróbuj online!
źródło
R,
4340 bajtówpryr::f
tworzy funkcję:Używa
DescTools::Fibonacci
do tworzenia pierwszychx+1
liczb Fibonacciego i sprawdza włączenie.x+1
ponieważ trzeci fibnum to 2, a to nie wystarczy, aby sprawdzić włączenie 3.Na szczęście
Desctools::Fibonacci(0)=0
jest to niezła gratka.-3 bajty dzięki MickyT
źródło
-1:x+1
zaoszczędzi ci bajt, ale0:45
uratuje trzy i obejmie wymagany zakrespryr::f(any(!(5*n^2+c(-4,4))^.5%%1))
.pryr
.Haskell , 31 bajtów
Wypróbuj online! Wykorzystuje to fakt, że dane wejściowe będą w zakresie od 0 do 1 000 000 000, dlatego musimy sprawdzić tylko pierwsze 45 liczb Fibonacciego.
f=0:scanl(+)1f
generuje nieskończoną listę liczb Fibonacciego,take 45f
jest listą pierwszych 45 liczb Fibonacciego ielem
sprawdza, czy dane wejściowe znajdują się na tej liście.Wersja nieograniczona: 36 bajtów
Wypróbuj online! Dla każdego
n
, biorąc pierwszen+3
liczby Fibonacciego zagwarantuje, żen
będzie na tej liście, jeśli jest to liczba Fibonacciego.Zauważ, że to podejście jest niesamowicie nieefektywne w przypadku wysokich liczb, które nie są liczbami Fibonacciego, ponieważ wszystkie
n+3
liczby Fibonacciego muszą zostać obliczone.źródło
JavaScript (ES6 bez operatora **), 44 bajty
Opiera się na stosunku kolejnych liczb Fibonacciego zbliżających się do złotego podziału. Wartość c jest ułamkową częścią danych wejściowych podzieloną przez złoty współczynnik - jeśli dane wejściowe to Fibonacciego, będzie to bardzo blisko 1, a wartość c-c² będzie bardzo mała.
Nie tak krótki jak niektóre inne odpowiedzi JS, ale działa w czasie O (1).
źródło
Julia 0,4 , 29 bajtów
Wypróbuj online!
Jeśli nie tak robisz odpowiedź Julii, daj mi znać. Nie jestem pewien, jak działa wejście w TIO.
źródło
!m=
) lub lambda (liczeniem->
). Co ważniejsze, nie powiedzie się to tak, jak jest 0 .R,
3231 bajtówPobiera dane wejściowe ze standardowego wejścia, zwraca
TRUE
lubFALSE
odpowiednio.źródło
Common Lisp,
6154 bajtówWypróbuj online!
Zmniejszenie rozmiaru w stosunku do poprzedniej wersji:
zrodził się pomysł, że do wygenerowania sekwencji liczb Fibonacciego potrzebne są tylko dwie zmienne, a nie trzy.
źródło
Mathematica, 33 bajty
źródło
@*
(a następnie upuścić finał@#&
)JS (ES6), 57 bajtów
Wykorzystuje metodę carusocomputing . Dużo bardziej golfista niż moja inna odpowiedź .
Bez golfa
źródło