O período mais longo iterativo quine


10

Como sabemos, um quine é um programa que gera seu próprio código-fonte. No entanto, também é possível escrever um programa que produza outro programa diferente, que produz o primeiro programa novamente. Por exemplo, o programa Python 2

x = '''x = {}
print 'print '+'"'*3+x.format("'"*3+x+"'"*3)+'"'*3'''
print 'print '+'"'*3+x.format("'"*3+x+"'"*3)+'"'*3

, quando executado, produzirá o seguinte texto:

print """x = '''x = {}
print 'print '+'"'*3+x.format("'"*3+x+"'"*3)+'"'*3'''
print 'print '+'"'*3+x.format("'"*3+x+"'"*3)+'"'*3"""

Quando executado como um programa Python, isso produzirá o código original novamente. Isso é chamado de quine iterativo . Como você precisa executá-lo duas vezes para recuperar o código original, dizemos que ele tem o período 2 . Mas é claro, períodos muito mais altos são possíveis.

Seu desafio é escrever um quine iterativo pelo maior período possível, em 100 bytes ou menos , no idioma de sua escolha. (Observe que meu exemplo acima não se encaixa nessa especificação, pois possui 119 bytes, incluindo a nova linha à direita.)

Observe as seguintes regras e esclarecimentos:

  • As regras usuais de quine se aplicam, ou seja, seu programa não pode usar recursos de linguagem que permitiriam acessar diretamente seu próprio código-fonte.
  • As saídas iteradas precisam eventualmente retornar ao código original e você deve incluir uma demonstração ou prova de que isso ocorrerá.
  • Você também deve incluir uma explicação de por que o ciclo é tão longo quanto você diz. Isso não precisa estar no nível de uma prova matemática, mas deve ser convincente para alguém familiarizado com o seu idioma. (Esta regra está aqui porque espero que algumas respostas envolvam números muito, muito grandes.)
  • Não há problema em dizer algo como "pelo menos 1.000.000 de iterações" em vez de fornecer o número exato, desde que você possa provar que é pelo menos esse tempo. Nesse caso, sua pontuação seria 1.000.000. Caso contrário, sua pontuação é o período da sua avaliação.
  • O limite de 100 bytes se aplica apenas ao seu programa inicial - os programas que ele produz podem ser mais longos, embora, é claro, eles precisem voltar a 100 bytes para gerar o código original.
  • Você pode assumir que sua máquina possui RAM e tempo de execução infinitos, mas não pode assumir tipos de dados de precisão ilimitados (como números inteiros) se o seu idioma não os possuir. Você pode assumir que não há limite para o tamanho da entrada que seu analisador pode manipular.
  • A pontuação mais alta vence.

Observe: existe um desafio existente chamado Quit Whining; Comece o Quining que também envolve a iteração de quines. No entanto, além de basear-se no mesmo conceito, esses são tipos de desafios completamente diferentes. O outro é código de golfe direto, enquanto este é (intencionalmente!) Realmente um problema de castor ocupado disfarçado. As técnicas necessárias para produzir uma boa resposta a essa pergunta provavelmente serão muito diferentes daquilo que é necessário para responder à outra pergunta, e isso é basicamente por design.


11
@LeakyNun Eu não sei se foi você ou um mod que excluiu sua resposta, mas talvez se eu explicar o que estava errado com você, você entenderá por que isso não é uma duplicata. Esta pergunta especifica um limite de 100 bytes no comprimento da fonte, portanto você não pode "atingir o nível máximo" usando esse método. Esse é o ponto principal desta questão. Para responder, o que você precisa fazer é publicar a versão mais longa que se encaixa em 100 caracteres e dizer qual é o período. O que você postou seria uma boa primeira tentativa, mas é muito improvável que seja o vencedor.
Nathaniel

11
@ O desafio é exatamente sobre a especificação de um número grande em um pequeno número de bytes, sim. Esse é todo o princípio em torno do qual ele foi projetado. A questão é: 3 ^^^ 3 é o número mais alto que você pode especificar em 100 bytes no seu idioma ou existe um número maior? É disso que trata este desafio. É o núcleo disso. É o que eu queria ver as pessoas fazerem. É super, super frustrante fechar com base em uma semelhança superficial com um desafio que não tem nada dessa estrutura.
Nathaniel

11
@Dave (segundo comentário), mas se você é esperto, não precisa se limitar à precisão da máquina. Eu esperaria que as respostas competitivas tivessem um período muito superior a 2 ^ (2 ^ 64).
Nathaniel

3
Então você prefere que seja fechado como uma duplicata de codegolf.stackexchange.com/q/18028/194 ?
Peter Taylor

11
@ PeterPaylor, esse é um tema muito mais próximo, mas ainda é um desafio muito diferente - imprimir um número é bem diferente de fazer algo várias vezes. É claro que eu preferiria que não ficasse fechado.
Nathaniel

Respostas:


10

PHP, período 2.100.000.000

Quem pensaria que isso é possível em PHP ?! :-)

Este é realmente o meu primeiro quine e tem 99 bytes de comprimento:

<?$i=1;$i*=21e8>$i;printf($a='<?$i=%d;$i*=21e8>$i;printf($a=%c%s%c,++$i,39,$a,39);',++$i,39,$a,39);

Embora o PHP suporte números maiores do que 2 * 10^8mudar integerpara double, o incremento não funciona mais (leva a um loop infinito) e eu não encontrei outra solução que se encaixe nos 100 bytes. Ainda.

A prova é bastante simples, pois conta apenas com cada iteração até atingir o ponto de redefinição em 2,1 bilhões.

Créditos a dave , que postou a abordagem em pseudo-código nos comentários e a Bob Twells , de quem copiei o código para obter uma quantidade mínima de PHP.

Programa de teste (sloooooow):

<?php
$o = file_get_contents('quine.php');
for ($i = 0; $i < 22e8; $i++) {
    if ($i%2==0) exec('php q > p'); else exec('php p > q');
    $a = file_get_contents(($i%2==0) ? 'p' : 'q');
    echo "\r" . str_pad($i,6,' ') . ":\t$a";
    if ($a == $o) {
        die;
    }
}

Bem, pelo menos eu sou o primeiro a responder.


11
Nota lateral: é da ordem de ~ 10 ^ 9.322219295.
LegionMammal978

8

Mathematica, período E8.5678 # 3 E2.1923 # 4 ~ E6.2695 # 3 # 2

Print[ToString[#0, InputForm], "[", #1 - 1 /. 0 -> "Nest[#!,9,9^9^99!]", "]"] & [Nest[#!,9,9^9^99!]]

Observe que as pontuações são descritas na notação Hyper-E . As iterações substituem o final Nest[#!,9,9^9^99!]pelas expansões decimais de Nest[#!,9,9^9^99!]- 1, Nest[#!,9,9^9^99!]- 2, Nest[#!,9,9^9^99!]- 3, ..., 3, 2, 1 e de volta a Nest[#!,9,9^9^99!].


os fatoriais não cresceriam mais rápido?
Maltysen 2/09/16

11
Não conheço o Mathematica, mas isso não é uma violação das regras de um quine - ler seu próprio código-fonte? ToString[#0, InputForm]
Daniero 02/09/19

então, apenas 9 !!!! não funciona? idk porque eu não tenho meu rhema mathematica comigo agora.
Maltysen

@ Maltysen Isso calcula o fatorial duplo do fatorial duplo de nove, ou (9 !!) !! ≈ 2,116870635 · 10¹²⁰²
LegionMammal978

@daniero Quer dizer, a ideia é semelhante a um CJam padrão {"_~"}_~, então eu acho que ele deve ser válido ...
LegionMammal978

5

R, período aleatório com expectativa 2 ^ 19936-0.5

f=function(){
    options(scipen=50)
    body(f)[[4]]<<-sum(runif(623))
    0
    cat("f=")
    print(f)
}

O gerador de números aleatórios padrão de R possui um período de 2 ^ 19937-1 e equidistribuição em 623 dimensões consecutivas. Assim, em algum lugar (mas apenas uma vez) em seu período haverá um vetor de zeros com 623 longos. Quando chegamos lá (e estamos alinhados com o início da sequência), a soma dos próximos 623 números U aleatórios [0,1] será zero e retornamos ao nosso programa original.

Observe que o programa passará com o mesmo estado diferente de zero várias vezes antes de retornar a zero. Por exemplo, a soma 311,5 é a mais provável, e existem muitas maneiras de isso acontecer, mas o RNG permite que o período 0 seja mais longo que o período 311,5.


Não tenho certeza qual pontuação você deseja atribuir esta entrada: P
JDL 02/09

11
Pelas regras: "Não há problema em dizer algo como" pelo menos 1.000.000 iterações "em vez de fornecer o número exato" Então, na minha opinião, é "pelo menos uma iteração" porque se tivermos muita sorte na primeira tentativa ...;)
YetiCGN 02/09

Ao contrário de muitas brechas comuns como "Eu posso gerar alguma entrada aleatória, a resposta está aí", esta é uma prova realmente clara de que a resposta precisa está fadada a ocorrer e é fornecida uma estimativa muito boa. Agradável!
Andreï Kostyrka 4/09/16

11
Uma vez que o programa retorne ao seu estado base uma vez, ele terá um período não aleatório de exatamente 2 ^ 19937-1.
JDL

A saída disso não corresponde ao programa real (falta um pouco de espaço em branco). Além disso, o estado não será preservado entre as chamadas do programa, portanto o período não será um número exato nem será consistente.
Jo King

1

JavaScript, período 9.007.199.254.700.000

Não vou ganhar, mas foi divertido trabalhar com JavaScript neste desafio:

a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),1-1||90071992547e5)

Segue o seguinte ciclo:

a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),1-1||90071992547e5)
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),9007199254700000-1||90071992547e5)
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),9007199254699999-1||90071992547e5)
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),9007199254699998-1||90071992547e5)
// etc...
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),3-1||90071992547e5)
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),2-1||90071992547e5)
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),1-1||90071992547e5)
a="a=%s;console.log(a,uneval(a),%.0f-1||90071992547e5)";console.log(a,uneval(a),9007199254700000-1||90071992547e5)
// and so on

Nota: Você pode torná-lo 18 bytes mais curto, enquanto remove apenas apenas 0,08% da pontuação, assim:

a="a=%s;console.log(a,uneval(a),%.0f-1||9e15)";console.log(a,uneval(a),1-1||9e15)

1

C, período 2.100.000.000

unsigned long long i;main(a){i=1;i*=21e8>i;printf(a="ungisned long long i;main(a){i=%d;i*=21e8>i;printf(a=%c%s%2$c,++i,34,a);}",++i,34,a);}

Baseado na resposta do PHP (obviamente). Será atualizado com explicação quando tiver tempo.


1

C (gcc) , 66 bytes, período 2 ^ 64

f(s){printf(s="f(s){printf(s=%c%s%1$c,34,s,%lu+1L);}",34,s,0+1L);}

Experimente online!

2 ^ 64 números estão disponíveis em um unsigned longnúmero inteiro. Portanto, um período de 2 ^ 64.


1

Python 2

9((99↑↑(9((99↑↑(9((99↑↑(9↑↑5-1 1))9)-1 1))9)-1 1))9)+1 1

99(99↑↑12)+1 1

b=0;s="print'b=%d;s=%r;exec s'%(-~b%eval('9**9'*eval('9**9'*eval('9**9'*9**9**9**9**9))),s)";exec s

Experimente online!

No código, as b=0alterações para b=1então b=2e assim por diante até chegar b=decimal expansion of the periode redefinir parab=0


11
9**9**9**9**9**9**9**9**9**9**9**9**9**9**9**9**9**9é muito maior que 9**9**99**99**99**99**99**99**99**99**99**99**99**99. Dito isto, você poderia fazer algo parecido eval('9**9'*eval('9**9'*eval('9**9'*9**9**9**9**9)))com números MUITO mais altos.
Bubbler

O que significa peroid?
SS Anne


11
@Mukundan Eu acho que você pode querer dizer período, mas não tenho certeza. Eu entendo o que é tetração.
SS Anne

@SSAnne desculpe, foi um erro de digitação, obrigado por apontá-lo
Mukundan 29/01

0

Gol> <> , 70 bytes, período 325883196621297064957600206175719056476804879488288708188003274919860959534770101079512433396348062803055739640225395758790852315876868469390603793729639715908136196505908165227136154287969475839017544811926036808089596209081885772040898530121921794489026069641113281250

Outro sábio conhecido como realmente grande (3.25E270)

":1=l8:*6+=S&Q~:'~'=Q~~'H#'||lPffXfX=?1:1=Q$~$~|:1)lPffXfX(Q?:|r2ssH##

Esta é realmente a versão alterada da resposta que eu coloquei no iterador de 500 bytes

":1=l8:*6+=S&Q~:'~'=Q~~'H#'||//if last is equal to 1 and length is 71, delete the delete char, if the last char is '~', delete and push 'H#', which will later return to 'H##', completing the cycle!
lPffXfX=?1:1=Q$~$~|          //if length is equal to 15^15^15, then start delete process(append ascii one)
:1)lPffXfX(Q?:|              //if the last character is not 1 (the delete checker), and length is less than 15^15^15, duplicate the last value and append
r2ssH##                      //push the " to the front and output the whole thing

Espero que eu tenha acertado o placar e não haja bugs. Não há nenhuma maneira real para realmente calcular esse valor, é teórico. Mas cara, esse é um número enorme !!!

Experimente online!

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.