Implementa il Fibonacci-quine


13

Un Quine è un programma che emette la sua fonte quando eseguito.

In questa sfida, dovresti creare un Fibonacci-quine, una variante del quine.


Che cos'è un Fibonacci-quine?

Un Fibonacci-quine è un programma che emette una modifica della sorgente con la seguente regola:

La fonte iniziale dovrebbe essere ...2.... In altre parole, la fonte dovrebbe contenere 2. (Perché 2? Se fosse 1, nessuno saprebbe se fosse il primo 1 o il secondo, anche il programma stesso)

Quando eseguito, dovresti generare la sorgente, ma solo il numero specifico (In questa fase, 2) è cambiato al numero successivo della sequenza fibonacci. Ad esempio ...3...,. Lo stesso vale per l'output e l'output dell'output, ecc. È possibile supportare numeri interi per un massimo di 2 ^ 32-1. Per numeri interi oltre tale limite, l'output successivo è a scelta.

Nota dell'OP

Mi piacerebbe davvero vedere una soluzione creativa per questo. Non riuscivo a pensare a un'unica soluzione per questo, poiché entrambi i due aspetti importanti della sfida, Fibonacci e Quine, non sono facili. Allora aspetterò!



4
La parte quine non aggiunge molto a questa sfida. Questo è solo "il prossimo valore nella sequenza di Fibonacci" più un costruttore universale di quine, come mostrano le risposte.

Sono d'accordo. Vorrei vedere una soluzione creativa anche per questo. Ma se vuoi una soluzione creativa così cattiva, allora perché non renderla una sfida al codice invece del code-golf. I criteri vincenti potrebbero essere il numero più alto di voti dopo un certo intervallo di tempo o qualcosa del genere.
Punto fisso

@FixedPoint Che dire di un 'Secondo criterio'? Qualcuno fa una soluzione creativa, do loro la generosità.
Matthew Roh,

@FixedPoint Questo è un concorso di popolarità
boboquack

Risposte:


8

Mathematica, 61 byte

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

Nota che c'è uno spazio finale. Questa è una funzione quine, ovvero il codice sopra riportato restituisce una funzione senza nome che, se chiamato, restituisce il codice stesso come una stringa (con il 2cambio al successivo numero di Fibonacci).

È stato sorprendentemente complicato arrivare al lavoro. L'idea di base è quella di prendere la funzione stessa (con #0) e sostituire un numero in quella funzione con quello successivo usando /. v:2 :> nextFib[v]. Tuttavia, nextFibnon verremmo valutati in questa fase, quindi non finiremmo davvero con il nuovo numero nel codice sorgente. Dopo aver cercato un po 'in giro per capire come forzare la valutazione immediata, ho trovato questo fantastico post su Mathematica.SE . La tecnica "standard" utilizza un Withblocco che forza la valutazione, ma la seconda risposta di WReach contiene un'alternativa più breve che utilizza l'integrato non documentato RuleConditionche forza anche la valutazione.

Il modo in cui calcoliamo il prossimo numero di Fibonacci è usando il fatto che il rapporto tra numeri consecutivi è approssimativamente il rapporto aureo 1.618 ... e questo è accurato fino all'arrotondamento. Quindi non abbiamo bisogno di tenere traccia degli ultimi due numeri e possiamo semplicemente farlo Round[GoldenRatio v]. Ciò non perderà mai precisione poiché Mathematica GoldenRationè un valore simbolico e pertanto Roundpuò sempre calcolare un risultato accurato.

In sintesi:

... #0 ... &

Una funzione senza nome, in cui si #0riferisce all'oggetto funzione stesso.

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

Trova a 2nell'albero delle espressioni della funzione (questo 2ovviamente corrisponde solo a se stesso), chiamalo ve sostituiscilo con ...

... RuleCondition[Round[GoldenRatio v]]

... il prossimo numero di Fibonacci.

ToString[...]

E converti l'albero di espressione risultante nella sua rappresentazione di stringa.


È bello sapere che a volte devi lavorare sodo :)
Greg Martin,

Non c'è un simbolo per il rapporto aureo?
caird coinheringaahing il

@cairdcoinheringaahing no.
Martin Ender,

7

CJam , 26 byte

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

Provalo online!

Probabilmente non del tutto ottimale. Semplicemente ripetiamo la sequenza di Fibonacci fino a quando il valore è maggiore dell'ultimo e utilizziamo il risultato come nuovo valore all'inizio del programma.


6
Thi..Questo presto?
Matthew Roh,




5

Python 3 , 81 79 byte

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

Provalo online!
Utilizza il rapporto aureo per calcolare il numero successivo


4

Gelatina , 14 byte

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

Provalo online! o verifica tutte le iterazioni richieste .

Come funziona

“×Ø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.

1

Rapido, 251 byte

Un po 'prolisso per me, ma non riesco a capire come accorciarlo:

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))))

Ungolfed:

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))))

Il mio problema è cercare di ottenere le virgolette nella nuova versione di s.



1

Javascript (ES6), 151 60 byte

Nuova versione, crediti a @ Leaky Nun

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

Vecchia versione :

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)

Sulla base di questo .


1
Benvenuti in PPCG! Speriamo che ti divertirai qui.
Leaky Nun,

@LeakyNun Speriamo risolto ora!
rbntd,

Versione golfizzata:x=i=>console.log('x='+x+';x('+(i*(5**.5+1)/2+.5|0)+')');x(2)
Leaky Nun

@LeakyNun wow, è breve! Ma non è troppo approssimativo? produce 50159 per i = 31000 anche se la risposta giusta dovrebbe essere 46368
rbntd

Non capisco. 31000non è un numero di Fibonacci.
Leaky Nun

1

dc , 35 byte

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

Una versione con iterazione (56 byte):

2[rsP1dsN[lN+lNrsNdlP[s.q]s.=.lFx]dsFxlNn91PP93P[dx]P]dx

1

Rapido, 235 byte

Questa è una versione migliorata di Caleb 's risposta .

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))))

0

Java (OpenJDK 8) , 239 byte

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);}}

Provalo online!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.