Implementar la fibonacci-quina

13

Un Quine es un programa que genera su fuente cuando se ejecuta.

En este desafío, debes hacer una Fibonacci-quine, una variante de la quine.


¿Qué es una fibonacci-quina?

Un fibonacci-quine es un programa que genera una modificación de la fuente mediante la siguiente regla:

La fuente inicial debería ser ...2.... En otras palabras, la fuente debe contener 2. (¿Por qué 2? Si fuera 1, nadie sabría si fue el primer 1 o el segundo, incluso el programa en sí)

Cuando se ejecuta, debe generar la fuente, pero solo el número específico (en esta etapa 2) cambió al siguiente número de la secuencia de Fibonacci. Por ejemplo, ...3.... Lo mismo ocurre con la salida y la salida de la salida, etc. Puede admitir números enteros de hasta 2 ^ 32-1. Para enteros por encima de ese límite, la próxima salida está a su elección.

Nota de OP

Realmente me gustaría ver una solución creativa para esto. No podría pensar en una solución única para esto, ya que los dos aspectos importantes del desafío, fibonacci y quine, no son fáciles. Estaré esperando entonces!

Matthew Roh
fuente
Relacionados .
Leaky Nun
44
La parte quine no agrega mucho a este desafío. Este es solo el "siguiente valor en la secuencia de Fibonacci" más un constructor universal de quine, como muestran las respuestas.
Estoy de acuerdo. Me gustaría ver una solución creativa para esto también. Pero si quieres una solución creativa tan mala, entonces ¿por qué no convertirla en un desafío de código en lugar de un código de golf? El criterio ganador podría ser el mayor número de votos después de un intervalo de tiempo o algo.
Punto fijo
@FixedPoint ¿Qué pasa con un 'Segundo criterio'? Alguien hace una solución creativa, les doy recompensas.
Matthew Roh
@FixedPoint Eso es un concurso de popularidad
boboquack

Respuestas:

8

Mathematica, 61 bytes

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

Tenga en cuenta que hay un espacio final. Esta es una función quine, es decir, el código anterior se evalúa como una función sin nombre que, si se llama, devuelve el código como una cadena (con el 2cambio al siguiente número de Fibonacci).

Fue sorprendentemente complicado llegar al trabajo. La idea básica es tomar la función en sí (con #0) y reemplazar un número en esa función con el siguiente usando /. v:2 :> nextFib[v]. Sin embargo, nextFibno sería evaluado en esta etapa, por lo que realmente no terminaríamos con el nuevo número en el código fuente. Después de buscar por un tiempo para descubrir cómo forzar la evaluación inmediata, encontré esta gran publicación en Mathematica.SE . La técnica "estándar" utiliza un Withbloque que fuerza la evaluación, pero la segunda respuesta de WReach contiene una alternativa más corta que usa el indocumentado incorporado RuleConditionque también fuerza la evaluación.

La forma en que calculamos el próximo número de Fibonacci es haciendo uso del hecho de que la razón de números consecutivos es aproximadamente la razón de oro 1.618 ... y esto es preciso hasta el redondeo. Por lo tanto, no necesitamos hacer un seguimiento de los dos últimos números y simplemente podemos hacerlo Round[GoldenRatio v]. Esto nunca perderá precisión, ya que Mathematica GoldenRationes un valor simbólico y, por Roundlo tanto , siempre puede calcular un resultado preciso.

En resumen:

... #0 ... &

Una función sin nombre, donde se #0refiere al objeto de la función en sí.

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

Busque un 2en el árbol de expresión de la función (esto, 2por supuesto, solo coincide), llámelo vy reemplácelo con ...

... RuleCondition[Round[GoldenRatio v]]

... el siguiente número de Fibonacci.

ToString[...]

Y convierta el árbol de expresión resultante en su representación de cadena.

Martin Ender
fuente
Es bueno saber que hay que trabajar duro en estos a veces :)
Greg Martin
¿No hay un símbolo para la proporción áurea?
caird coinheringaahing
@cairdcoinheringaahing no.
Martin Ender
7

CJam , 26 bytes

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

Pruébalo en línea!

Probablemente no del todo óptimo. Simplemente iteramos la secuencia de Fibonacci hasta que el valor es mayor que el último y usamos el resultado como el nuevo valor al comienzo del programa.

Martin Ender
fuente
66
Thi..This temprano?
Matthew Roh
5

Python 3 , 81 79 bytes

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

Pruébalo en línea!
Utiliza la proporción áurea para calcular el siguiente número

varilla
fuente
4

Jalea , 14 bytes

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

Pruébalo en línea! o verificar todas las iteraciones requeridas .

Cómo funciona

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

Swift, 251 bytes

Un poco detallado para mí, pero no puedo entender cómo acortarlo:

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

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

Mi problema es tratar de obtener las citas de la nueva versión de s.

Caleb Kleveter
fuente
1

Cheddar , 136 bytes

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

Pruébalo en línea!

Monja permeable
fuente
1

Javascript (ES6), 151 60 bytes

Nueva versión, créditos a @ Leaky Nun

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

Versión antigua :

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)

Basado en esto .

rbntd
fuente
1
Bienvenido a PPCG! Esperamos que la pases muy bien aquí.
Leaky Nun
@LeakyNun ¡Con suerte arreglado ahora!
rbntd
Versión de golf:x=i=>console.log('x='+x+';x('+(i*(5**.5+1)/2+.5|0)+')');x(2)
Leaky Nun
@LeakyNun wow, eso es corto! ¿Pero no es demasiado aproximado? produce 50159 para i = 31000 aunque la respuesta correcta debería ser 46368
rbntd
No entiendo. 31000No es un número de Fibonacci.
Leaky Nun
1

cc , 35 bytes

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

Una versión con iteración (56 bytes):

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

Rápido, 235 bytes

Esta es una versión mejorada de la respuesta 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
fuente
0

Java (OpenJDK 8) , 239 bytes

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

Pruébalo en línea!

Monja permeable
fuente