Implementar o Fibonacci-quine

13

Um Quine é um programa que gera sua fonte quando executado.

Neste desafio, você deve fazer um Fibonacci-quine, uma variante do quine.


O que é um Fibonacci-quine?

Um Fibonacci-quine é um programa que gera uma modificação da fonte pela seguinte regra:

A fonte inicial deve ser ...2.... Em outras palavras, a fonte deve conter 2. (Por que 2? Se fosse 1, ninguém saberia se era o primeiro 1 ou o segundo, até o próprio programa)

Quando executado, você deve gerar a fonte, mas apenas o número específico (neste estágio 2) mudou para o próximo número da sequência de fibonacci. Por exemplo ...3...,. O mesmo vale para a saída, e a saída da saída, etc. Você pode suportar números inteiros até 2 ^ 32-1. Para números inteiros acima desse limite, a próxima saída é a sua escolha.

Nota do OP

Eu realmente gostaria de ver uma solução criativa para isso. Não consegui pensar em uma solução única para isso, pois os dois aspectos importantes do desafio, fibonacci e quine, não são fáceis. Estarei esperando então!

Matthew Roh
fonte
Relacionado .
Leaky Nun
4
A parte quine não adiciona muito a esse desafio. Este é apenas o "próximo valor na sequência de Fibonacci" mais um construtor universal de quine, como mostram as respostas.
Concordo. Eu gostaria de ver uma solução criativa para isso também. Mas se você quer uma solução criativa tão ruim, por que não torná-la um desafio de código em vez de golfe de código? O critério de vencimento pode ser o maior número de votos após um intervalo de tempo ou algo assim.
Ponto fixo
@FixedPoint Que tal um 'Segundo critério'? Alguém faz uma solução criativa, eu dou a eles recompensa.
Matthew Roh
@FixedPoint Isso é um -concurso de popularidade
boboquack

Respostas:

8

Mathematica, 61 bytes

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

Observe que há um espaço à direita. Esta é uma função quine, ou seja, o código acima é avaliado para uma função sem nome que, se chamada, retorna o próprio código como uma string (com a 2alteração para o próximo número de Fibonacci).

Isso foi surpreendentemente complicado para começar a trabalhar. A idéia básica é pegar a função em si (com #0) e substituir um número nessa função pela próxima usando /. v:2 :> nextFib[v]. No entanto, nextFibnão seríamos avaliados nesta fase, para que não terminássemos com o novo número no código-fonte. Depois de pesquisar um pouco para descobrir como forçar a avaliação imediata, encontrei este ótimo post no Mathematica.SE . A técnica "padrão" usa um Withbloco que força a avaliação, mas a segunda resposta do WReach contém uma alternativa mais curta usando o built-in não documentado RuleConditionque também força a avaliação.

A maneira como calculamos o próximo número de Fibonacci é usando o fato de que a proporção de números consecutivos é aproximadamente a proporção áurea de 1,618 ... e isso é preciso até o arredondamento. Portanto, não precisamos acompanhar os dois últimos números e podemos simplesmente fazê-lo Round[GoldenRatio v]. Isso nunca perderá precisão, pois o Mathematica GoldenRationé um valor simbólico e, portanto, Roundsempre pode calcular um resultado preciso.

Em suma:

... #0 ... &

Uma função sem nome, em que #0se refere ao próprio objeto da função.

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

Encontre a 2na árvore de expressão da função (é 2claro que isso só corresponde a si mesmo), chame-o ve substitua-o por ...

... RuleCondition[Round[GoldenRatio v]]

... o próximo número de Fibonacci.

ToString[...]

E converta a árvore de expressão resultante em sua representação de sequência.

Martin Ender
fonte
É bom saber que você tem que trabalhar duro para estes, por vezes :)
Greg Martin
Não existe um símbolo para a proporção áurea?
caird coinheringaahing
@cairdcoinheringaahing no.
Martin Ender
7

CJam , 26 bytes

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

Experimente online!

Provavelmente não é o ideal. Simplesmente iteramos a sequência de Fibonacci até que o valor seja maior que o último e usamos o resultado como o novo valor no início do programa.

Martin Ender
fonte
6
Thi ... Tão cedo?
Matthew Roh
6

CJam , 20 bytes

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

Experimente online!

jimmy23013
fonte
Uau, 20 bytes: Estou sem palavras ...
Mr. Xcoder
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)))

Experimente online!
Usa a proporção áurea para calcular o próximo número

Cajado
fonte
4

Gelatina , 14 bytes

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

Experimente online! ou verifique todas as iterações necessárias .

Como 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
fonte
1

Rápido, 251 bytes

Um pouco detalhado para mim, mas não consigo descobrir como reduzi-lo:

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

Meu problema é tentar obter as cotações da nova versão do s.

Caleb Kleveter
fonte
1

Queijo 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

Experimente online!

Freira Furada
fonte
1

Javascript (ES6), 151 60 bytes

Nova versão, créditos para @ Leaky Nun

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

Versão antiga :

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)

Com base nisso .

rbntd
fonte
1
Bem-vindo ao PPCG! Esperamos que você se divirta aqui.
Freira vazando
@LeakyNun Espero que seja corrigido agora!
Rbntd
Versão golfe:x=i=>console.log('x='+x+';x('+(i*(5**.5+1)/2+.5|0)+')');x(2)
Freira
@LeakyNun uau, isso é curto! Mas não é muito aproximado? gera 50159 para i = 31000, embora a resposta correta deva ser 46368
rbntd
Eu não entendo 31000não é um número de Fibonacci.
Freira vazando
1

dc , 35 bytes

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

Uma versão com iteração (56 bytes):

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

Rápido, 235 bytes

Esta é uma versão melhorada do Caleb 's resposta .

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

Experimente online!

Freira Furada
fonte