Zaimplementuj Fibonacciego

13

Quine to program, który wysyła swoje źródło po uruchomieniu.

W tym wyzwaniu powinieneś zrobić Fibonacciego, wariant tego quina.


Co to jest Fibonacci-quine?

Fibonacci-quine to program, który generuje modyfikację źródła według następującej reguły:

Pierwotnym źródłem powinno być ...2.... Innymi słowy, źródło powinno zawierać 2. (Dlaczego 2? Gdyby to był 1, nikt nie wiedziałby, czy to byłby pierwszy 1 czy drugi, nawet sam program)

Po uruchomieniu powinieneś wypisać źródło, ale tylko konkretna liczba (Na tym etapie 2) zmieniła się na następną liczbę sekwencji fibonacciego. Na przykład ...3.... To samo dotyczy wyjścia, wyjścia, itp. Możesz obsługiwać liczby całkowite do 2 ^ 32-1. Dla liczb całkowitych przekraczających ten limit, następne wyjście jest do wyboru.

Notatka OP

Naprawdę chciałbym zobaczyć kreatywne rozwiązanie tego problemu. Nie mogłem wymyślić jednego rozwiązania tego problemu, ponieważ oba ważne aspekty wyzwania, Fibonacci i Quine, nie są łatwe. Będę wtedy czekać!

Matthew Roh
źródło
Związane .
Leaky Nun
4
Część quine niewiele wnosi do tego wyzwania. To tylko „następna wartość w sekwencji Fibonacciego” plus uniwersalne konstruktory quine, jak pokazują odpowiedzi.
Zgadzam się. Chciałbym również zobaczyć kreatywne rozwiązanie tego problemu. Ale jeśli chcesz tak kreatywnego rozwiązania, dlaczego nie uczynić go wyzwaniem kodowym zamiast golfowego. Kryterium wygranej może być najwyższa liczba głosów po pewnym czasie lub coś takiego.
Naprawiono punkt
@FixedPoint Co z „drugimi kryteriami”? Ktoś tworzy kreatywne rozwiązanie, daję im nagrodę.
Matthew Roh
@FixedPoint To konkurs popularności
boboquack

Odpowiedzi:

8

Mathematica, 61 bajtów

ToString[#0 /. v:2 :> RuleCondition[Round[GoldenRatio v]]] & 

Zauważ, że jest spacja. Jest to quine funkcji, tzn. Powyższy kod przekształca się w funkcję nienazwaną, która, jeśli zostanie wywołana, zwraca sam kod jako ciąg znaków (ze 2zmianą na następny numer Fibonacciego).

To było zaskakująco trudne, aby dostać się do pracy. Podstawową ideą jest przejęcie samej funkcji (z #0) i zastąpienie liczby w tej funkcji inną za pomocą /. v:2 :> nextFib[v]. Jednak nextFibna tym etapie nie zostaniemy poddani ocenie, więc tak naprawdę nie otrzymalibyśmy nowego numeru w kodzie źródłowym. Po chwili zastanowienia, aby wymusić natychmiastową ocenę, znalazłem ten świetny post na Mathematica.SE . Technika „standardowa” wykorzystuje Withblok, który wymusza ocenę, ale druga odpowiedź WReach zawiera krótszą alternatywę z wykorzystaniem nieudokumentowanej wbudowanej, RuleConditionktóra także wymusza ocenę.

Sposób, w jaki obliczamy następną liczbę Fibonacciego, polega na tym, że stosunek kolejnych liczb jest w przybliżeniu złotym współczynnikiem 1,618 ... i jest to dokładne do zaokrąglenia. Nie musimy więc śledzić dwóch ostatnich liczb i możemy to po prostu zrobić Round[GoldenRatio v]. To nigdy nie straci precyzji, ponieważ Mathematica GoldenRationjest wartością symboliczną i dlatego Roundzawsze może obliczyć dokładny wynik.

W podsumowaniu:

... #0 ... &

Funkcja bez nazwy, gdzie #0odnosi się do samego obiektu funkcji.

... /. v:2 :> ...

Znajdź 2w drzewie wyrażeń funkcji (to 2oczywiście pasuje tylko do siebie), wywołaj ją vi zamień na ...

... RuleCondition[Round[GoldenRatio v]]

... kolejny numer Fibonacciego.

ToString[...]

I przekonwertuj powstałe drzewo wyrażeń na jego reprezentację ciągu.

Martin Ender
źródło
Miło jest wiedzieć, że czasem trzeba ciężko nad tym pracować :)
Greg Martin
Czy nie ma symbolu złotego podziału?
caird coinheringaahing
@cairdcoinheringaahing no.
Martin Ender,
7

CJam , 26 bajtów

2{0X{_@+_W$>!}go;\;"_~"}_~

Wypróbuj online!

Prawdopodobnie nie do końca optymalny. Po prostu iterujemy sekwencję Fibonacciego, aż wartość będzie większa od ostatniej, i wykorzystamy wynik jako nową wartość na początku programu.

Martin Ender
źródło
6
To wcześnie?
Matthew Roh
6

CJam , 20 bajtów

2{\5mq)*)Y/io"_~"}_~

Wypróbuj online!

jimmy23013
źródło
Wow, 20 bajtów:
Zaniemówiłem
5

Python 3 , 81 79 bajtów

s='s=%r;print(s%%(s,round(%s*(1+5**.5)/2)))';print(s%(s,round(2*(1+5**.5)/2)))

Wypróbuj online!
Wykorzystuje złoty współczynnik do obliczenia następnej liczby

Pręt
źródło
4

Galaretka , 14 bajtów

“×Øp+.ḞṭØv”Ṙv2

Wypróbuj online! lub sprawdź wszystkie wymagane iteracje .

Jak to działa

“×Øp+.ḞṭØv”Ṙv2  Main link. No arguments.

“×Øp+.ḞṭØv”     Set the left argument and return value to the string "×Øp+.ḞṭØv".
           Ṙ    Print a string representation of the return value and yield the
                unaltered return value.
            v2  Evaluate the return value as a Jelly program with left argument 2.
 ×Øp                Multiply the left argument by the golden ratio.
    +.              Add 0.5 to the resulting product.
      Ḟ             Floor; round the resulting sum down to the nearest integer.
        Øv          Yield the string "Øv".
       ṭ            Tack; append the result to the left to the result to the right.
Dennis
źródło
1

Szybki, 251 bajtów

Dla mnie trochę gadatliwy, ale nie mogę wymyślić, jak go skrócić:

import Foundation;var n="\"";var u="\\";var s="import Foundation;var n=%@%@%@%@;var u=%@%@%@%@;var s=%@%@%@;print(String(format:s,n,u,n,n,n,u,u,n,n,s,n,(round(%f*(1+sqrt(5))/2))))";print(String(format:s,n,u,n,n,n,u,u,n,n,s,n,(round(2*(1+sqrt(5))/2))))

Nie golfowany:

import Foundation
var n="\""
var u="\\"
var s="import Foundation;var n=%@%@%@%@;var u=%@%@%@%@;var s=%@%@%@;print(String(format:s,n,u,n,n,n,u,u,n,n,s,n,(round(%f*(1+sqrt(5))/2))))"
print(String(format:s,n,u,n,n,n,u,u,n,n,s,n,(round(2*(1+sqrt(5))/2))))

Moim problemem jest próba uzyskania cytatów wokół nowej wersji s.

Caleb Kleveter
źródło
1

Cheddar , 136 bajtów

let b=1;for(let a=1;a<2;a=b-a){b+=a};let s='let b=1;for(let a=1;a<%i;a=b-a){b+=a};let s=%s;print s%b%@"39+s+@"39';print s%b%@"39+s+@"39

Wypróbuj online!

Leaky Nun
źródło
1

JavaScript (ES6), 151 60 bajtów

Nowa wersja, napisy dla @ Leaky Nun

x=i=>console.log('x='+x+';x('+(i*(5**.5+1)/2+.5|0)+')');x(2)

Stara wersja :

x=i=>{var s=Math.sqrt(5),a=1;f=n=>{return Math.ceil((((1+s)/2)**n-((1-s)/2)**n)/s)};while(f(++a)<=i);console.log('x='+String(x)+';x('+f(a)+')');};x(2)

Na podstawie tego .

rbntd
źródło
1
Witamy w PPCG! Mamy nadzieję, że będziesz się dobrze bawić tutaj.
Leaky Nun
@LeakyNun Mam nadzieję, że teraz naprawione!
rbntd
Wersja golfowa:x=i=>console.log('x='+x+';x('+(i*(5**.5+1)/2+.5|0)+')');x(2)
Leaky Nun
@LeakyNun wow, to krótko! Ale czy nie jest to zbyt przybliżone? wyprowadza 50159 dla i = 31000, chociaż prawidłowa odpowiedź powinna wynosić 46368
rbntd
Nie rozumiem. 31000nie jest liczbą Fibonacciego.
Leaky Nun
1

dc , 35 bajtów

2[r9k5v1+2/*.5+0k1/n91PP93P[dx]P]dx

Wersja z iteracją (56 bajtów):

2[rsP1dsN[lN+lNrsNdlP[s.q]s.=.lFx]dsFxlNn91PP93P[dx]P]dx
eush77
źródło
1

Szybki, 235 bajtów

Jest to ulepszona wersja Caleb „s odpowiedź .

import Foundation;var n="\"",u="\\",s="import Foundation;var n=%@%@%@%@,u=%@%@%@%@,s=%@%@%@;print(String(format:s,n,u,n,n,n,u,u,n,n,s,n,(round(%f*(1+sqrt(5))/2))))";print(String(format:s,n,u,n,n,n,u,u,n,n,s,n,(round(2*(1+sqrt(5))/2))))
Nathan Piercy
źródło
0

Java (OpenJDK 8) , 239 bajtów

interface a{static void main(String[]p){int a=1,b=1;for(;a<2;a=b-a)b+=a;String s="interface a{static void main(String[]p){int a=1,b=1;for(;a<%d;a=b-a)b+=a;String s=%c%s%c;System.out.printf(s,b,34,s,34);}}";System.out.printf(s,b,34,s,34);}}

Wypróbuj online!

Leaky Nun
źródło