Implémenter le Fibonacci-quine

13

Un Quine est un programme qui sort sa source lors de son exécution.

Dans ce défi, vous devez faire une Fibonacci-quine, une variante de la quine.


Qu'est-ce qu'une Fibonacci-quine?

Un Fibonacci-quine est un programme qui génère une modification de la source selon la règle suivante:

La source initiale devrait être ...2.... En d'autres termes, la source doit contenir 2. (Pourquoi 2? Si c'était 1, personne ne saurait si c'était le premier 1 ou le second, même le programme lui-même)

Lors de l'exécution, vous devez générer la source, mais seul le numéro spécifique (à ce stade 2) a été remplacé par le numéro suivant de la séquence fibonacci. Par exemple ...3...,. Il en va de même pour la sortie et la sortie de la sortie, etc. Vous pouvez prendre en charge des nombres entiers jusqu'à 2 ^ 32-1. Pour les entiers supérieurs à cette limite, la sortie suivante est sur votre choix.

Note de l'OP

J'aimerais vraiment voir une solution créative pour cela. Je ne pouvais pas penser à une seule solution pour cela, car les deux aspects importants du défi, fibonacci et quine, ne sont pas faciles. J'attendrai alors!

Matthew Roh
la source
Connexes .
Leaky Nun
4
La partie quine n'ajoute pas beaucoup à ce défi. Ceci est juste "la prochaine valeur dans la séquence de Fibonacci" plus un constructeur de quine universel, comme le montrent les réponses.
Je suis d'accord. J'aimerais aussi voir une solution créative. Mais si vous voulez une solution créative si mauvaise, alors pourquoi ne pas en faire un code-challenge au lieu de code-golf. Le critère de gain pourrait être le plus grand nombre de votes après un certain intervalle de temps ou quelque chose.
Point fixe
@FixedPoint Qu'en est-il d'un «deuxième critère»? Quelqu'un fait une solution créative, je leur donne de la générosité.
Matthew Roh
@FixedPoint C'est un concours de popularité
boboquack

Réponses:

8

Mathematica, 61 octets

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

Notez qu'il y a un espace de fin. Il s'agit d'une fonction quine, c'est-à-dire que le code ci-dessus est évalué comme une fonction sans nom qui, s'il est appelé, renvoie le code lui-même sous forme de chaîne (avec le 2changement au numéro de Fibonacci suivant).

C'était étonnamment difficile de se rendre au travail. L'idée de base est de prendre la fonction elle-même (avec #0) et de remplacer un nombre dans cette fonction par la suivante en utilisant /. v:2 :> nextFib[v]. Cependant, nextFibne serait pas évalué à ce stade, donc nous ne nous retrouverions pas vraiment avec le nouveau numéro dans le code source. Après avoir cherché pendant un certain temps pour comprendre comment forcer une évaluation immédiate, j'ai trouvé cet excellent article sur Mathematica.SE . La technique "standard" utilise un Withbloc qui force l'évaluation, mais la deuxième réponse de WReach contient une alternative plus courte utilisant la fonction intégrée non documentée RuleConditionqui force également l'évaluation.

La façon dont nous calculons le prochain nombre de Fibonacci est en utilisant le fait que le rapport des nombres consécutifs est à peu près le nombre d'or 1,618 ... et cela est précis jusqu'à l'arrondi. Nous n'avons donc pas besoin de garder une trace des deux derniers chiffres et pouvons simplement le faire Round[GoldenRatio v]. Cela ne perdra jamais sa précision car Mathematica GoldenRationest une valeur symbolique et Roundpeut donc toujours calculer un résultat précis.

En résumé:

... #0 ... &

Une fonction sans nom, où #0fait référence à l'objet de fonction lui-même.

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

Trouvez un 2dans l'arborescence d'expression de la fonction (cela 2ne correspond bien sûr qu'à lui-même), appelez-le vet remplacez-le par ...

... RuleCondition[Round[GoldenRatio v]]

... le prochain numéro de Fibonacci.

ToString[...]

Et convertissez l'arbre d'expression résultant en sa représentation sous forme de chaîne.

Martin Ender
la source
C'est agréable de savoir que vous devez parfois travailler dur à cela :)
Greg Martin
N'y a-t-il pas un symbole pour le nombre d'or?
caird coinheringaahing
@cairdcoinheringaahing no.
Martin Ender
7

CJam , 26 octets

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

Essayez-le en ligne!

Probablement pas tout à fait optimal. Nous itérons simplement la séquence de Fibonacci jusqu'à ce que la valeur soit supérieure à la dernière et utilisons le résultat comme nouvelle valeur au début du programme.

Martin Ender
la source
6
Thi..This tôt?
Matthew Roh
6

CJam , 20 octets

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

Essayez-le en ligne!

jimmy23013
la source
Wow, 20 octets: je suis sans voix ...
M. Xcoder
5

Python 3 , 81 79 octets

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

Essayez-le en ligne!
Utilise le nombre d'or pour calculer le nombre suivant

Barre
la source
4

Gelée , 14 octets

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

Essayez-le en ligne! ou vérifiez toutes les itérations requises .

Comment ça fonctionne

“×Ø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
la source
1

Swift, 251 octets

Un peu bavard pour moi, mais je ne sais pas comment le raccourcir:

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

Non golfé:

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

Mon problème est d'essayer d'obtenir les citations autour de la nouvelle version de s.

Caleb Kleveter
la source
1

Cheddar , 136 octets

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

Essayez-le en ligne!

Leaky Nun
la source
1

Javascript (ES6), 151 60 octets

Nouvelle version, crédits à @ Leaky Nun

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

Ancienne version :

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)

Sur cette base .

rbntd
la source
1
Bienvenue chez PPCG! Nous espérons que vous passerez un bon moment ici.
Leaky Nun
@LeakyNun Avec un peu de chance maintenant!
rbntd
Version golfée:x=i=>console.log('x='+x+';x('+(i*(5**.5+1)/2+.5|0)+')');x(2)
Leaky Nun
@LeakyNun wow, c'est court! Mais n'est-ce pas trop approximatif? il produit 50159 pour i = 31000 bien que la bonne réponse devrait être 46368
rbntd
Je ne comprends pas. 31000n'est pas un numéro de Fibonacci.
Leaky Nun
1

DC , 35 octets

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

Une version avec itération (56 octets):

2[rsP1dsN[lN+lNrsNdlP[s.q]s.=.lFx]dsFxlNn91PP93P[dx]P]dx
eush77
la source
1

Swift, 235 octets

Il s'agit d'une version améliorée de la réponse de Caleb .

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
la source
0

Java (OpenJDK 8) , 239 octets

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

Essayez-le en ligne!

Leaky Nun
la source