Golf um quine para o bem!


204

Usando o seu idioma preferido, jogue golfe com calma .

Um quine é um programa de computador não vazio que não recebe entrada e produz uma cópia de seu próprio código-fonte como sua única saída.

Sem trapaça - isso significa que você não pode simplesmente ler o arquivo de origem e imprimi-lo. Além disso, em muitos idiomas, um arquivo vazio também é uma opção: também não é considerado uma opção legítima.

Sem erros de erro - já existe um desafio separado para erros de erro.

Pontos para:

  • Código menor (em bytes)
  • Solução mais ofuscada / obscura
  • Usando idiomas esotéricos / obscuros
  • Utilizando com sucesso idiomas difíceis de jogar golfe

O seguinte snippet de pilha pode ser usado para obter uma visão rápida da pontuação atual em cada idioma e, assim, saber quais idiomas têm respostas existentes e que tipo de destino você deve atingir:


4
Você não quer dizer "Golpeie-o para um bem maior!"?
Mateen Ulhaq

50
@muntoo é uma peça de teatro "Aprenda um Haskell para um grande bem".
Rafe Kettler

Respostas:


106

Hexagonia , comprimento lateral 17 16, 816 705 bytes

180963109168843880558244491673953327577233938129339173058720504081484022549811402058271303887670710274969455065557883702369807148960608553223879503892017157337685576056512546932243594316638247597075423507937943819812664454190530214807032600083287129465751195839469777849740055584043374711363571711078781297231590606019313065042667406784753422844".".>.@.#.#.#.#.#.#.#.>.(...........................<.".......".".>./.4.Q.;.+.<.#.>...........................<.".....".".>.#.#.>.N.2.'.\.>.............=.=......._.<.".....".".>.>.;.'.=.:.\.>.......................<."...".".>.\.'.%.'.<.#.>..............._.....<."...".".>.#.#.>.<.#.>...............=.=.<.".".".>.#.\.'.R./.>.................<.".!.........../.>.

Experimente online!

Isto é o que parece desdobrado:

                1 8 0 9 6 3 1 0 9 1 6 8 8 4 3 8
               8 0 5 5 8 2 4 4 4 9 1 6 7 3 9 5 3
              3 2 7 5 7 7 2 3 3 9 3 8 1 2 9 3 3 9
             1 7 3 0 5 8 7 2 0 5 0 4 0 8 1 4 8 4 0
            2 2 5 4 9 8 1 1 4 0 2 0 5 8 2 7 1 3 0 3
           8 8 7 6 7 0 7 1 0 2 7 4 9 6 9 4 5 5 0 6 5
          5 5 7 8 8 3 7 0 2 3 6 9 8 0 7 1 4 8 9 6 0 6
         0 8 5 5 3 2 2 3 8 7 9 5 0 3 8 9 2 0 1 7 1 5 7
        3 3 7 6 8 5 5 7 6 0 5 6 5 1 2 5 4 6 9 3 2 2 4 3
       5 9 4 3 1 6 6 3 8 2 4 7 5 9 7 0 7 5 4 2 3 5 0 7 9
      3 7 9 4 3 8 1 9 8 1 2 6 6 4 4 5 4 1 9 0 5 3 0 2 1 4
     8 0 7 0 3 2 6 0 0 0 8 3 2 8 7 1 2 9 4 6 5 7 5 1 1 9 5
    8 3 9 4 6 9 7 7 7 8 4 9 7 4 0 0 5 5 5 8 4 0 4 3 3 7 4 7
   1 1 3 6 3 5 7 1 7 1 1 0 7 8 7 8 1 2 9 7 2 3 1 5 9 0 6 0 6
  0 1 9 3 1 3 0 6 5 0 4 2 6 6 7 4 0 6 7 8 4 7 5 3 4 2 2 8 4 4
 " . " . > . @ . # . # . # . # . # . # . # . > . ( . . . . . .
  . . . . . . . . . . . . . . . . . . . . . < . " . . . . . .
   . " . " . > . / . 4 . Q . ; . + . < . # . > . . . . . . .
    . . . . . . . . . . . . . . . . . . . . < . " . . . . .
     " . " . > . # . # . > . N . 2 . ' . \ . > . . . . . .
      . . . . . . . = . = . . . . . . . _ . < . " . . . .
       . " . " . > . > . ; . ' . = . : . \ . > . . . . .
        . . . . . . . . . . . . . . . . . . < . " . . .
         " . " . > . \ . ' . % . ' . < . # . > . . . .
          . . . . . . . . . . . _ . . . . . < . " . .
           . " . " . > . # . # . > . < . # . > . . .
            . . . . . . . . . . . . = . = . < . " .
             " . " . > . # . \ . ' . R . / . > . .
              . . . . . . . . . . . . . . . < . "
               . ! . . . . . . . . . . . / . > .
                . . . . . . . . . . . . . . . .

Ah, bem, essa foi a montanha-russa emocional ... eu parei de contar o número de vezes que alternei entre "haha, isso é loucura" e "espera, se eu fizer isso , deve ser realmente factível". As restrições impostas ao código pelas regras de layout da Hexagony eram ... severas.

Pode ser possível reduzir o comprimento lateral em 1 ou 2 sem alterar a abordagem geral, mas será difícil (apenas as células #atualmente não estão sendo usadas e estão disponíveis para o decodificador). No momento, também não tenho absolutamente nenhuma idéia de como uma abordagem mais eficiente, mas tenho certeza de que existe. Vou pensar sobre isso nos próximos dias e talvez tentar jogar de um lado, antes de adicionar uma explicação e tudo.

Bem, pelo menos, eu provei que é possível ...

Alguns scripts CJam para minha própria referência futura:


51
Caro pete, o que é isso?
Conor O'Brien

2
Quanto tempo levou para fazer isso?
Adnan

3
@AandN Eu tenho brincado com conceitos para um "modelo" geral desde ontem e agora (que não envolveu nenhum teste real ... apenas digitando algumas coisas em uma grade 7x7 e vendo se poderia funcionar .. Descartar provavelmente meia dúzia de abordagens já existentes). A codificação atual levou esta noite ... talvez três horas, eu diria.
Martin Ender

10
As palavras não podem explicar como estou surpreso ao ver isso em ação com o IDE esotérico passo a passo ... Para quem quiser entender isso, esse hexágono codifica a parte do "decodificador" em um número inteiro impresso com !e depois com um espelho /na 2ª última linha, ele entra no decodificador para imprimir o código do decodificador para concluir o quine. Isso tem um uso milagroso de <e >lê o número inteiro muito grande multilinha e construiu a área para armazenar o decodificador. Eu adoraria saber o que "dezenas de abordagens" estão sendo consideradas?
Sunny Pun

3
Explicação? ---
MD XF

77

MySQL, 167 caracteres

SELECT REPLACE(@v:='SELECT REPLACE(@v:=\'2\',1+1,REPLACE(REPLACE(@v,\'\\\\\',\'\\\\\\\\\'),\'\\\'\',\'\\\\\\\'\'));',1+1,REPLACE(REPLACE(@v,'\\','\\\\'),'\'','\\\''));

Está certo. :-)

Eu realmente escrevi esse aqui. Foi originalmente publicado no meu site .


72

GolfScript, 2 bytes

1

(observe a nova linha) Isso coloca o número 1 na pilha. No final do programa, o GolfScript imprime todos os itens da pilha (sem espaços no meio) e depois imprime uma nova linha.

Este é um verdadeiro quine (conforme listado na pergunta), porque na verdade executa o código; não apenas "lê o arquivo de origem e o imprime" (diferente da submissão do PHP).


Para outro exemplo, aqui está um programa GolfScript para imprimir 12345678:

9,(;
  1. 9: pressione 9 para a pilha
  2. ,: consome o 9 como argumento, empurre o array [0 1 2 3 4 5 6 7 8]para a pilha
  3. (: consome a matriz como argumento, empurre a matriz [1 2 3 4 5 6 7 8]e o item 0para a pilha
  4. ;: descartar o item superior da pilha

A pilha agora contém a matriz [1 2 3 4 5 6 7 8]. Isso é gravado na saída padrão sem espaços entre os elementos, seguido por uma nova linha.


18
Ou PowerShell, ou PHP :-)
Joey

6
Você não voltou no tempo e deu ao inventor a idéia de inventar o GolfScript, não é?
Mateen Ulhaq

78
Tecnicamente, 1não é um problema no GolfScript: ele gera 1\n, onde \ndenota uma nova linha. No entanto, o programa de dois caracteres 1\n é uma opção.
Ilmari Karonen

17
O programa one-char \nprovavelmente também é?
Lynn

10
O pseudônimo de quine é literalmente um programa que imprime sua própria fonte. Não acho que haja restrições arbitrárias à "estrutura".
Hugo Zink 24/09

71

Brain-Flak , 9.8e580 1.3e562 9.3e516 12818 11024 4452 4332 4240 4200 4180 3852 3656 3616 3540 2485 + 3 = 2488 bytes

Agora se encaixa no universo observável!

(())(()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(()()())(())(()()()()())(())(())(())(())(()()()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(()()())(())(()()()()())(())(())(())(())(())(())(()())(())(())(())(()())(()()()())(())(()()()()())(()())(()())(()())(()()())(())(()())(())(()()()()())(()())(()()()()())(())(())(())(())(())(()())(())(())(())(()()()()())(())(())(()()()()())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(()())(()())(()())(()())(())(()()()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(()()())(())(())(()()())(()())(())(()()()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(())(())(())(()()())(())(())(()()())(())(())(()()())(())(()()()()())(()())(()()()()())(()()())(())(()()())(())(())(())(()())(()()())(()())(())(()()()()())(()())(())(()()())(())(()()()()())(())(())(())(()()())(())(())(())(()())(())(()())(()()()())(())(())(()()()()())(()())(()())(())(()()())(())(())(())(())(()()())(()())(())(())(()()()()())(())(())(()()()()())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(())(()()()()())(()())(())(()()())(())(()()()()())(()()()()())(())(()()())(())(())(()())(())(()()()()())(())(()()()()())(())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(())(()()()()())(()())(())(()()())(())(())(()())(())(()()()()())(()())(()()()()())(())(()()())(())(())(()()()()())(())(()()()()())(())(())(())(()())(())(()()()()())(())(())(()())(())(()())(())(()())(()())(()())(()())(())(()()()()())(()())(())(()()()()())(())(()()())(())(())(()())(())(()()()()())(()())(()()()()())(())(()()())(())(())(())(()())(()()()())(())(())(()())(())(()()()()())(())(())(()()()()())(())(())(()()()()())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()())(()())(()())(()())(())(()()())(())(())(()())(())(()()()()())(()())(()()()()())(()()())(())(())(()())(())(())(()()()()())(()()()())(()())(()())(()()())(())(()())(())(()()()()())(()())(()()()()())(())(())(())(()()()())(()()()())(()())([[]]){({}()<(([{}]())<{({}())<>(((((()()()()()){}){}){}())[()])<>{({}())<>{}({}(((()()()){}())){}{})<>{({}())<>({}(((()()()()()){})){}{}())<>{{}<>({}(((()()()()){}){}){})(<>)}}<>(({})[()()])<>}}{}<>({}(<()>)<><{({}<>)<>}<>>){({}<>)<>}{}(<>)<>{({}<>)<>}{}(((((((()()()()()){}){}){}))()))>){({}()<((({}[()])()))>)}{}<>{({}<>)<>}{}>)}{}<>{({}<>)<>}<>

Experimente online!


Explicação

Este Quine funciona como a maioria dos Quines em línguas esotéricas; possui duas partes: um codificador e um decodificador. O codificador é todos os parênteses no início e o decodificador é a parte mais complexa no final.

Uma maneira ingênua de codificar o programa seria colocar na pilha o valor ASCII de cada caractere no decodificador. Essa não é uma idéia muito boa, porque o Brain-Flak usa apenas 8 caracteres ( ()<>[]{}), então você acaba pagando alguns bytes para codificar muito pouca informação. Uma idéia mais inteligente e usada até agora é atribuir cada uma das 8 chaves a um número muito menor (1-8) e convertê-las nos valores ASCII com nosso decodificador. Isso é bom porque não custa mais do que 18 bytes para codificar um caractere em oposição aos 252 anteriores.

No entanto, este programa também não. Ele se baseia no fato de que os programas Brain-Flak são todos balanceados para codificar as 8 chaves com números de até 5. Ele os codifica da seguinte maneira.

(       -> 2
<       -> 3
[       -> 4
{       -> 5
),>,],} -> 1

Todos os chavetas são atribuídos a 1 porque podemos usar o contexto para determinar qual deles precisamos usar em um cenário específico. Isso pode parecer uma tarefa assustadora para um programa Brain-Flak, mas na verdade não é. Tomemos, por exemplo, as seguintes codificações com as chaves abertas decodificadas e as chaves fechadas substituídas por um .:

(.
((..
<([.{...

Espero que você possa ver que o algoritmo é bastante simples, lemos da esquerda para a direita, cada vez que encontramos uma chave aberta, empurramos sua chave próxima para uma pilha imaginária e, quando encontramos uma ., exibimos o valor mais alto e o colocamos no lugar do .. Essa nova codificação economiza um enorme número de bytes no codificador, enquanto nos perde apenas um punhado de bytes no decodificador.

Explicação de baixo nível

Trabalho em progresso


25
Acho que você venceu pela solução mais longa para um desafio de código-golfe ...
Mego

18
Acabou de fazer o maior golfe individual da história do PPCG Nope. 9.8e580 ainda é impressionante.
Dennis

19
+1 para encaixar no universo observável. Além disso, com o TIO Nexus, o link permanente deve caber na resposta. tio.run/nexus/…
Dennis

3
... muito grande golfe ...
Destructible Lemon

3
Eu acho que você ganha para a maioria dos bytes cortados
Christopher

68

Prelúdio , 5157 4514 2348 1761 1537 664 569 535 423 241 214 184 178 175 169 148 142 136 136 bytes

Agradecimentos ao Sp3000 por salvar 3 bytes.

Isso é bastante longo ... (tudo bem, ainda é longo ... pelo menos está superando o quesito Brainfuck C # mais curto nesse desafio agora) mas é o primeiro quine que eu me descobri (meus envios de Lua e Julia são na verdade apenas traduções de técnicas padrão de quine em outras línguas) e , até onde sei, ninguém escreveu uma palavra em Prelude até agora, então estou realmente muito orgulhoso disso. :)

7( -^^^2+8+2-!( 6+ !
  ((#^#(1- )#)8(1-)8)#)4337435843475142584337433447514237963742423434123534455634423547524558455296969647344257)

Esse grande número de dígitos é apenas uma codificação do código principal, e é por isso que o quine é tão longo.

Os dígitos que codificam o quine foram gerados com este script CJam .

Isso requer um intérprete compatível com o padrão, que imprime caracteres (usando os valores como códigos de caracteres). Portanto, se você estiver usando o interpretador Python, precisará definir NUMERIC_OUTPUT = False.

Explicação

Primeiro, algumas palavras sobre o Prelude: cada linha no Prelude é uma "voz" separada que manipula sua própria pilha. Essas pilhas são inicializadas com um número infinito de 0s. O programa é executado coluna por coluna, onde todos os comandos na coluna são executados "simultaneamente" com base nos estados anteriores da pilha. Os dígitos são empurrados para a pilha individualmente; portanto 42, pressione a 4e depois a 2. Não há como empurrar números maiores diretamente, você precisará adicioná-los. Os valores podem ser copiados das pilhas adjacentes com ve ^. Os loops no estilo Brainfuck podem ser introduzidos com parênteses. Veja o link no título para mais informações.

Aqui está a idéia básica do quine: primeiro, introduzimos muitos dígitos na pilha que codifica o núcleo do quine. O referido núcleo, em seguida, pega esses dígitos, decodifica-os para imprimir a si próprio e depois imprime os dígitos como eles aparecem no código (e no final )).

Isso é um pouco complicado pelo fato de eu ter que dividir o núcleo em várias linhas. Originalmente, eu tinha a codificação no início, mas precisava preencher as outras linhas com o mesmo número de espaços. É por isso que as pontuações iniciais foram tão grandes. Agora coloquei a codificação no final, mas isso significa que primeiro preciso pular o núcleo, pressionar os dígitos e voltar ao início e fazer a impressão.

A codificação

Como o código possui apenas duas vozes, ee adjacência é cíclica ^e vé sinônimo. Isso é bom porque vtem de longe o maior código de caracteres, portanto, evitá-lo sempre usando ^torna a codificação mais simples. Agora todos os códigos de caracteres estão no intervalo de 10 a 94, inclusive. Isso significa que eu posso codificar cada caractere com exatamente dois dígitos decimais. Porém, há um problema: alguns caracteres, notadamente o avanço de linha, têm um zero em sua representação decimal. Isso é um problema porque os zeros não são facilmente distinguíveis da parte inferior da pilha. Felizmente, há uma correção simples para isso: compensamos os códigos de caracteres 2, portanto, temos um intervalo de 12 a 96, inclusive, que ainda se encaixa confortavelmente em dois dígitos decimais. Agora, de todos os caracteres que podem aparecer no programa Prelude,0tem um 0 em sua representação (50), mas realmente não precisamos 0. Essa é a codificação que estou usando, pressionando cada dígito individualmente.

No entanto, como estamos trabalhando com uma pilha, as representações são empurradas ao contrário. Então, se você olhar para o final da codificação:

...9647344257

Divida em pares e inverta, subtraia dois e procure os códigos de caracteres:

57 42 34 47 96
55 40 32 45 94
 7  (     -  ^

onde 32é corresponde a espaços. O núcleo faz exatamente essa transformação e depois imprime os caracteres.

O nucleo

Então, vamos ver como esses números são realmente processados. Primeiro, é importante observar que os parênteses correspondentes não precisam estar na mesma linha no Prelúdio. Só pode haver um parêntese por coluna; portanto, não há ambiguidade em que os parênteses pertençam um ao outro. Em particular, a posição vertical do parêntese de fechamento é sempre irrelevante - a pilha que é verificada para determinar se o loop termina (ou é ignorado completamente) sempre será a que possui (.

Queremos executar o código exatamente duas vezes - na primeira vez, pulamos o núcleo e pressionamos todos os números no final, na segunda vez em que executamos o núcleo. De fato, depois de rodarmos o núcleo, empurraremos todos esses números novamente, mas, como o loop termina depois, isso é irrelevante. Isso fornece o seguinte esqueleto:

7(
  (                   )43... encoding ...57)

Primeiro, pressionamos 7a primeira voz - se não fizermos isso, nunca entraremos no loop (para o esqueleto é importante que isso seja diferente de zero ... por que especificamente 7veremos mais adiante) . Então entramos no loop principal. Agora, a segunda voz contém outro loop. Na primeira passagem, esse loop será ignorado porque a segunda pilha está vazia / contém apenas 0s. Então, pulamos direto para a codificação e colocamos todos esses dígitos na pilha. O que 7colocamos na primeira pilha ainda está lá, então o loop se repete.

Desta vez, também há um 7na segunda pilha, então inserimos loop na segunda voz. O loop na segunda voz foi projetado para que a pilha fique vazia novamente no final, portanto, é executada apenas uma vez. Isso também esgotará a primeira pilha ... Então, quando deixamos o loop na segunda voz, pressionamos todos os dígitos novamente, mas agora 7a primeira pilha foi descartada, de modo que o loop principal termina e o programa termina.

A seguir, vejamos o primeiro loop no núcleo real. Fazer as coisas simultaneamente com um (ou )é bastante interessante. Marquei o corpo do loop aqui com =:

-^^^2+8+2-!
(#^#(1- )#)
 ==========

Isso significa que a coluna que contém (não é considerada parte do loop (os caracteres são executados apenas uma vez e mesmo se o loop for ignorado). Mas a coluna que contém o ) faz parte do loop e é executada uma vez em cada iteração.

Então começamos com um single -, que transforma 7a primeira pilha em -7... novamente, mais sobre isso mais tarde. Quanto ao loop real ...

O loop continua enquanto a pilha de dígitos não foi esvaziada. Ele processa dois dígitos por vez. O objetivo desse loop é decodificar a codificação, imprimir o caractere e, ao mesmo tempo, mudar a pilha de dígitos para a primeira voz. Então, essa parte primeiro:

^^^
#^#

A primeira coluna move o 1 dígito para a primeira voz. A segunda coluna copia os 10 dígitos para a primeira voz, enquanto também copia o dígito de volta para a segunda voz. A terceira coluna move essa cópia de volta para a primeira voz. Isso significa que a primeira voz agora tem 1 dígito duas vezes e 10 dígitos no meio. A segunda voz possui apenas outra cópia dos 10 dígitos. Isso significa que podemos trabalhar com os valores no topo das pilhas e ter certeza de que restam duas cópias na primeira pilha para mais tarde.

Agora recuperamos o código de caractere dos dois dígitos:

2+8+2-!
(1- )#

A parte inferior é um pequeno loop que apenas diminui os 10 dígitos para zero. Para cada iteração, queremos adicionar 10 ao topo. Lembre-se de que o primeiro 2não faz parte do loop, então o corpo do loop é na verdade o +8+2que adiciona 10 (usando o 2pressionado anteriormente) e empurra o outro 2. Portanto, quando terminamos o loop, a primeira pilha realmente tem a base- 10 valor e outro 2. Subtraímos esse 2 com -para contabilizar o deslocamento na codificação e imprimir o caractere com !. O #apenas descarta o zero no final do loop inferior.

Depois que esse loop é concluído, a segunda pilha fica vazia e a primeira pilha mantém todos os dígitos na ordem inversa (e a -7na parte inferior). O resto é bastante simples:

( 6+ !
8(1-)8)#

Este é o segundo loop do núcleo, que agora imprime todos os dígitos. Para fazer isso, precisamos 48 em cada dígito para obter o código de caractere correto. Fazemos isso com um loop simples que executa 8vezes e adiciona 6cada vez. O resultado é impresso com !e 8no final é para a próxima iteração.

Então, o que acontece com o -7? Sim, 48 - 7 = 41qual é o código de caractere de ). Magia!

Finalmente, quando terminamos esse loop, descartamos o 8que pressionamos #para garantir que deixemos o loop externo na segunda voz. Nós pressionamos todos os dígitos novamente e o programa termina.



19
Martin, você precisa parar em algum lugar.
seequ

3
Eu amo que isso tenha mais de 5000 bytes de golfe em geral, além de um reconhecimento ao Sp3000 por salvar 3 deles.
Kamil Drakari

2
@KamilDrakari Esses foram os últimos 3 bytes, então é um grande negócio. ;)
Martin Ender

57

Hexagonia , comprimento lateral 11, 314 bytes

164248894991581511673077637999211259627125600306858995725520485910920851569759793601722945695269172442124287874075294735023125483.....!/:;.........)%'=a':\....................\...................\..................\.................\................\...............\..............\..$@.........\$><>'?2='%.<\:;_;4Q

Experimente online!


Versão antiga:

Hexagonia , comprimento lateral 11, 330 bytes

362003511553420961423766261426252539048636523959468260999944549820033581478284471415809677091006384959302453627348235790194699306179..../:{;+'=1P'%'a{:..\.....................\...................\..................\.................\................\...............\..............\.............\!$><........\..@>{?2'%<......:;;4Q/

Experimente online!

Codificador: Experimente online!

O programa é aproximadamente equivalente a este código Python: Experimente online!

Código desdobrado:

           3 6 2 0 0 3 5 1 1 5 5
          3 4 2 0 9 6 1 4 2 3 7 6
         6 2 6 1 4 2 6 2 5 2 5 3 9
        0 4 8 6 3 6 5 2 3 9 5 9 4 6
       8 2 6 0 9 9 9 9 4 4 5 4 9 8 2
      0 0 3 3 5 8 1 4 7 8 2 8 4 4 7 1
     4 1 5 8 0 9 6 7 7 0 9 1 0 0 6 3 8
    4 9 5 9 3 0 2 4 5 3 6 2 7 3 4 8 2 3
   5 7 9 0 1 9 4 6 9 9 3 0 6 1 7 9 . . .
  . / : { ; + ' = 1 P ' % ' a { : . . \ .
 . . . . . . . . . . . . . . . . . . . . \
  . . . . . . . . . . . . . . . . . . . \ 
   . . . . . . . . . . . . . . . . . . \  
    . . . . . . . . . . . . . . . . . \   
     . . . . . . . . . . . . . . . . \    
      . . . . . . . . . . . . . . . \     
       . . . . . . . . . . . . . . \      
        . . . . . . . . . . . . . \       
         ! $ > < . . . . . . . . \        
          . . @ > { ? 2 ' % < . .         
           . . . . : ; ; 4 Q / .          

Dois .s leva 1 bit. Quaisquer outros caracteres têm 1 bit e um dígito de base 97.

Explicação

Clique nas imagens para ver em tamanho maior. Cada parte da explicação possui o código Python correspondente para ajudar a entender.

Parte de dados

Em vez da estrutura complexa utilizada em algumas outras respostas (com <, "e algumas outras coisas), eu apenas deixar passar o IP através da metade inferior.

Dados

Primeiro, o IP é executado através de muitos números e no-op's ( .) e espelhos ( \). Cada dígito é anexado ao número na memória, portanto, no final, o valor da memória é igual ao número no início do programa.

mem = 362003511...99306179

! imprime

stdout.write(str(mem))

e $pula para o próximo >.

A partir do <. Se o valor da memória memfor falso ( <= 0ou seja, a condição mem > 0não for atendida), concluímos a impressão do programa e devemos sair. O IP seguiria o caminho superior.

Saída

(deixe o IP ser executado em todo o mundo por cerca de 33 comandos antes de pressionar o @(que encerra o programa) porque colocá-lo em qualquer outro lugar gera alguns bytes adicionais)

Se for verdade, seguimos o caminho inferior, somos redirecionados algumas vezes e executamos mais alguns comandos antes de atingir outra condição.

# Python                    # Hexagony
# go to memory cell (a)     # {
a = 2                       # ?2
# go to memory cell (b)     # '
b = mem % a                 # %

Agora a memória fica assim:

Mem1

Se o valor for verdadeiro:

if b > 0:

o seguinte código é executado:

# Python                    # Hexagony
b = ord('Q')                # Q
b = b*10+4                  # 4
# Note: now b == ord('.')+256*3
stdout.write(chr(b%256))    # ;
stdout.write(chr(b%256))    # ;

Veja a explicação detalhada do Q4em resposta HelloWorld Hexagony de MartinEnder . Em resumo, esse código é impresso .duas vezes.

Originalmente, planejei que isso fosse impresso .uma vez. Quando eu vim com isso (imprima .duas vezes) e o implementei, cerca de 10 dígitos foram salvos.

Então,

b = mem // a                # :

Aqui está um fato importante que percebi que me salvou cerca de 14 dígitos: você não precisa estar onde começou.


Para entender o que estou dizendo, vamos fazer uma analogia com o namorado. (pule isso se você já entendeu)

Dado o código

while a != 0:
    b, a = a * 2, 0
    a, b = b, 0
    print(a)

Supondo que deixemos aser o valor da célula atual e bo valor da célula certa, uma tradução direta disso para BF é:

[             # while a != 0:
    [->++<]       # b, a = a * 2, 0
    >[-<+>]       # a, b = b, 0
    <.            # print(a)
]

No entanto, observe que não precisamos estar na mesma posição o tempo todo durante o programa. Podemos deixar que o valor aseja o que somos no início de cada iteração, então temos este código:

[             # while a != 0:
    [->++<]       # b, a = a * 2, 0
                  # implicitly let (a) be at the position of (b) now
    .             # print(a)
]

que é vários bytes mais curto.


Além disso, o comportamento de quebra de esquina também me \impede de ter um espelho lá - sem ele eu não seria capaz de ajustar os dígitos (+2 dígitos para o \próprio e +2 dígitos para um não pareado .à direita dele, sem mencionar o bandeiras)

(detalhes:

  • O IP entra no canto inferior esquerdo, indo para a esquerda
  • É deformado no canto direito, ainda continua à esquerda
  • Ele encontra um \que reflete isso, agora segue direto
  • Ele entra no canto e é deformado novamente no canto inferior esquerdo

)


Se o valor (da operação mod 2 acima) for falso (zero), seguiremos este caminho:

# Python                 # Hexagony   # Memory visualization after execution
b = mem // a             # :          # click here
base = ord('a') # 97     # a
y = b % base             # '%
offset = 33              # P1
z = y + offset           # ='+
stdout.write(chr(z))     # ;          # click here
mem = b // base          # {:         # click here

Não vou explicar muito detalhadamente aqui, mas o deslocamento na verdade não é exatamente 33, mas é congruente ao 33mod 256. E chrtem um implícito % 256.


3
Cara, isso é um monte de no-ops
Jo King

26
Eu ri de "Para entender o que estou dizendo, vamos fazer uma analogia [BrainFuck]". Apenas em PPCG ... :)
Lynn

2
Rolei 3 vezes até o topo da resposta para votá-lo novamente, apenas para descobrir que já o fiz ... #
NieDzejkob /

2
310 bytes , aproveitando o novo espaço, diminuindo o número
Jo King

2
308 bytes ocupando ainda mais espaço
Jo King

46

Vim, 11 bytes

q"iq"qP<Esc>hqP
  • iq"qP<Esc>: Insira manualmente uma duplicata do texto que deve estar fora da gravação.
  • q"e hqP: Grave o interior diretamente no ""registro sem nome , para que possa ser colado no meio. O hé o único reposicionamento necessário; se você colocá-lo dentro da macro, ele será colado no resultado.

Editar

Uma observação sobre a gravação com q": O registro sem nome ""é uma coisa engraçada. Não é realmente um registro verdadeiro como os outros, pois o texto não é armazenado lá. Na verdade, é um ponteiro para algum outro registro (geralmente "-para exclusões sem nova linha, "0para arranjos ou "1para exclusões com uma nova linha). q"quebra as regras; ele realmente escreve para "0. Se você ""já estava apontando para algum registro que não seja "0, q"substituirá, "0mas ""permanecerá inalterado. Quando você inicia um novo Vim, ""aponta automaticamente para "0, então você está bem nesse caso.

Basicamente, o Vim é estranho e com erros.


esperar por que não faz este trabalho para me
Destrutível Lemon

@DestructibleWatermelon Não posso dizer com certeza, mas uma explicação é mais provável. Provavelmente deveria tê-lo escrito antes, pois pode expulsar as pessoas. Leia a edição.
Udioica 14/10

você provavelmente deve colocar algo sobre como urgente you algo antes de executar pode ajudar
Destrutível Lemon

Por que você não costuma exibir pressionando a tecla <Esc>? Parte deste bloco Unicode “Control Pictures”
mbomb007 15/16

4
@ mbomb007 A <Esc>notação é padrão nos mapeamentos do Vim ( :help <>) e é isso que o vimgolf.com usa. Qualquer vimgolfer experiente será usado para lê-lo. Quanto ao unicode, tenho que apertar os olhos para ler as letras minúsculas, e elas obscurecem o método de digitá-las e pesquisar no arquivo de ajuda.
Udioica 15/10/16

44

Cubix , 20 bytes

3434Qu$v@!<"OOw\o;/"

Quase consegui o \o/ ...

Líquido :

    3 4
    3 4
Q u $ v @ ! < "
O O w \ o ; / "
    . .
    . .

Experimente online

Experimente aqui !

Notas Adicionais

História de fundo

Depois de me impressionar ao ler esta ótima resposta do @ ais523, comecei a pensar em jogar mais. Afinal, havia algumas no-ops lá, e isso não parecia muito comprimido. No entanto, como a técnica que sua resposta (e a minha também) usa, exige que o código abranja linhas completas, foi necessária uma economia de pelo menos 12 bytes. Houve uma observação em sua explicação que realmente me fez pensar:

Sobre o assunto do golfe ainda mais, [...] seria necessário [...] alguma outra maneira de representar a face superior do cubo [...]

Então, de repente, quando me levantei e me afastei para pegar algo para beber, ocorreu-me: e se o programa não usasse códigos de caracteres, mas números para representar a face superior? Isso é especialmente curto se o número que estamos imprimindo tiver 2 dígitos. Cubix tem 3 instruções de um byte para empurrar números de dois dígitos: N, Se Q, que empurram 10, 32e 34, respectivamente, de modo que este deve ser bastante golfy, pensei.

A primeira complicação dessa idéia é que a face superior agora está cheia de números inúteis, por isso não podemos mais usá-la. A segunda complicação é que a face superior tem um tamanho que é o tamanho do cubo ao quadrado e precisa ter um tamanho uniforme; caso contrário, um número também terminaria na posição inicial do ponteiro da instrução, levando a uma pilha poluída. Devido a essas complicações, meu código precisava caber em um cubo de tamanho 2 (que pode conter 'apenas' 24 bytes, então tive que jogar pelo menos 21 bytes). Além disso, como as faces superior e inferior são inutilizáveis, eu tinha apenas 16 bytes efetivos.

Então comecei escolhendo o número que se tornaria metade da face superior. Comecei com N(10), mas isso não deu certo devido à abordagem que eu estava adotando para imprimir tudo. De qualquer maneira, comecei de novo e usei S(32) por algum motivo. Isso resultou em uma solução adequada, ou assim eu pensei. Tudo funcionou muito bem, mas as aspas estavam faltando. Ocorreu-me então que o Q(34) seria realmente útil. Afinal, 34 é o código de caractere da aspas duplas, que nos permite mantê-lo na pilha, economizando (2, no layout que eu usei então) bytes preciosos. Depois de alterar um pouco a rota IP, tudo o que restou foi um exercício para preencher os espaços em branco.

Como funciona

O código pode ser dividido em 5 partes. Vou examiná-los um por um. Observe que estamos codificando as faces do meio na ordem inversa, porque o modelo da pilha é o primeiro a entrar na última saída.

Etapa 1: Imprimir a face superior

As instruções irrelevantes foram substituídas por no-ops ( .). O IP inicia a terceira linha, à esquerda, apontando para o leste. A pilha está (obviamente) vazia.

    . .
    . .
Q u . . . . . .
O O . . . . . .
    . .
    . .

O IP termina na posição mais à esquerda na quarta linha, apontando para oeste, prestes a quebrar para a posição mais à direita na mesma linha. As instruções executadas são (sem o caractere de fluxo de controle):

QOO
Q   # Push 34 (double quotes) to the stack
 OO # Output twice as number (the top face)

A pilha contém apenas 34, representando o último caractere da fonte.

Etapa 2: codifique a quarta linha

Esse pouco faz o que você espera: codificar a quarta linha. O IP começa com aspas duplas no final dessa linha e segue para oeste, pressionando os códigos de cada caractere até encontrar uma aspas dupla correspondente. Essa aspas duplas correspondente também é o último caractere na quarta linha, porque o IP quebra novamente quando atinge a borda esquerda.

Efetivamente, o IP moveu uma posição para a esquerda e a pilha agora contém a representação da quarta linha em códigos de caracteres e ordem inversa.

Etapa 3: enviar outra cotação

Precisamos fazer outra cotação, e que melhor maneira de reciclar Qno início do programa, abordando-o da direita? Isso tem o bônus adicional de que o IP é executado diretamente na cotação que codifica a terceira linha.

Aqui está a versão líquida para esta etapa. As intruções irrelevantes foram substituídas por no-ops novamente, as no-ops executadas foram substituídas por hashtags ( #) para fins de ilustração e o IP inicia no último caractere na quarta linha.

    . .
    . .
Q u $ . . . . .
. . w \ . . / .
    . #
    . #

O IP termina na terceira linha na primeira instrução, prestes a quebrar para o final dessa linha porque está apontando para o oeste. As seguintes instruções (excluindo o fluxo de controle) são executadas:

$uQ
$u  # Don't do anthing
  Q # Push the double quote

Essa aspas duplas representa aquela no final da terceira linha.

Etapa 4: Codificando a Terceira Linha

Isso funciona exatamente da mesma maneira que na etapa 2, portanto, procure uma explicação.

Etapa 5: Imprimir a pilha

A pilha agora contém a quarta e a terceira linhas, na ordem inversa; portanto, tudo o que precisamos fazer agora é imprimi-la. O IP começa na penúltima instrução na terceira linha, movendo-se para oeste. Aqui está a parte relevante do cubo (novamente, partes irrelevantes foram substituídas por no-ops).

    . .
    . .
. . . v @ ! < .
. . . \ o ; / .
    . .
    . .

Este é um loop, como você pode ter visto / esperado. O corpo principal é:

o;
o  # Print top of stack as character
 ; # Delete top of stack

O loop termina se o item superior for 0, o que só acontece quando a pilha está vazia. Se o loop terminar, o @é executado, finalizando o programa.


gostaria de poder upvote isso mais
MickyT

Bounties são sempre bem vindos ;-)
Lucas

42

Javascript ES6 - 21 bytes

$=_=>`$=${$};$()`;$()

Eu chamo isso de quine "O Bling Quine".

Às vezes, você precisa jogar golfe com estilo.


Você !$=_=>`!$=${$}()`()economiza 2 bytes?
Downgoat

Invalid assignment left hand side. Gostaria que funcionasse :(
Mama Fun Roll

1
@ TùxCräftîñg eliminar parênteses em torno dos literais do modelo só funciona em funções de protótipo nativas, como Array.prototype.join.
Mama Fun rolo

2
Hmm, não tenho certeza. Escrevi isso há mais de um ano (era considerado válido na época) e não acompanho as alterações das regras do quine com muita atenção. No entanto, adicionar alertou console.logapós a função de seta e colocar a cadeia de modelo entre parênteses funcionaria.
Mama Fun Roll

3
Além disso, se você executar isso no concole, ele substituirá $ (função jQuery) neste site e a função upvote não funcionará mais. :)
Steven Palinkas

41

Brainf * ck (755 caracteres)

Isso se baseia em uma técnica desenvolvida por Erik Bosman (ejbosman em cs.vu.nl). Observe que o "Quine do ESultanik!" o texto é realmente necessário para que seja um quine!

->++>+++>+>+>++>>+>+>+++>>+>+>++>+++>+++>+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+>+>++>>>+++>>>>>+++>+>>>>>>>>>>>>>>>>>>>>>>+++>>>>>>>++>+++>+++>+>>+++>>>+++>+>+++>+>++>+++>>>+>+>+>+>++>+++>+>+>>+++>>>>>>>+>+>>>+>+>++>+++>+++>+>>+++>+++>+>+++>+>++>+++>++>>+>+>++>+++>+>+>>+++>>>+++>+>>>++>+++>+++>+>>+++>>>+++>+>+++>+>>+++>>+++>>>+++++++++++++++>+++++++++++++>++++++>+++++++++++++++>++++++++++>+++>+++>++++>++++++++++++++>+++>++++++++++>++++>++++++>++>+++++>+++++++++++++++>++++++++>++++>++++++++++++>+++++++++++++++>>++++>++++++++++++++>+++>+++>++++>++++++>+++>+++++++++>++++>+>++++>++++++++++>++++>++++++++>++>++++++++++>+>+++++++++++++++>+++++++++++++
ESultanik's Quine!
+[[>>+[>]+>+[<]<-]>>[>]<+<+++[<]<<+]>>+[>]+++[++++++++++>++[-<++++++++++++++++>]<.<-<]

13
Essa é uma maneira inteligente de fazer isso.
22611 Peter Olson

13
Como funciona?
proud haskeller

3
@proudhaskeller IIRC, a parte anterior ESultanik's Quine!configura a memória como uma pilha de codificação ESultanik's Quine!e para a frente, com dois bytes de memória para cada caractere (o valor ASCII compensa 0x1F). O bit final de código percorre a memória, primeiro reproduzindo programaticamente os ++>+++…códigos para cada caractere e depois imprimindo os caracteres.
ESultanik

4
@CatsAreFluffy Eles são obrigados a ser uma solução! Embora seja verdade que eles pudessem ser removidos, também seria necessário alterar o código anterior para manter a propriedade quine.
ESultanik 7/03/16

1
Isso é verdade. Também as novas linhas são necessárias.
CalculatorFeline

36

Hexagonia , comprimento lateral 15 14 13 12, 616 533 456 383 bytes

Após vários dias de golfe cuidadoso, reorganizando os loops e recomeçando, finalmente consegui reduzi-lo para um hexágono lateral 12.

1845711724004994017660745324800783542810548755533855003470320302321248615173041097895645488030498537186418612923408209003405383437728326777573965676397524751468186829816614632962096935858"">./<$;-<.....>,.........==.........<"......."">'....>+'\.>.........==........<"......"">:>)<$=<..>..............$..<"...."">\'Q4;="/@>...............<"....."">P='%<.>.............<"..!'<.\=6,'/>

Experimente online!

Desdobrado:

            1 8 4 5 7 1 1 7 2 4 0 0
           4 9 9 4 0 1 7 6 6 0 7 4 5
          3 2 4 8 0 0 7 8 3 5 4 2 8 1
         0 5 4 8 7 5 5 5 3 3 8 5 5 0 0
        3 4 7 0 3 2 0 3 0 2 3 2 1 2 4 8
       6 1 5 1 7 3 0 4 1 0 9 7 8 9 5 6 4
      5 4 8 8 0 3 0 4 9 8 5 3 7 1 8 6 4 1
     8 6 1 2 9 2 3 4 0 8 2 0 9 0 0 3 4 0 5
    3 8 3 4 3 7 7 2 8 3 2 6 7 7 7 5 7 3 9 6
   5 6 7 6 3 9 7 5 2 4 7 5 1 4 6 8 1 8 6 8 2
  9 8 1 6 6 1 4 6 3 2 9 6 2 0 9 6 9 3 5 8 5 8
 " " > . / < $ ; - < . . . . . > , . . . . . .
  . . . = = . . . . . . . . . < " . . . . . .
   . " " > ' . . . . > + ' \ . > . . . . . .
    . . . = = . . . . . . . . < " . . . . .
     . " " > : > ) < $ = < . . > . . . . .
      . . . . . . . . . $ . . < " . . . .
       " " > \ ' Q 4 ; = " / @ > . . . .
        . . . . . . . . . . . < " . . .
         . . " " > P = ' % < . > . . .
          . . . . . . . . . . < " . .
           ! ' < . \ = 6 , ' / > . .
            . . . . . . . . . . . .

Embora não pareça o código Hexagony mais eficiente, o tipo de codificação que eu usei é otimizado para execuções mais longas de no-ops, o que é algo que você evitaria.

Explicação

Isso supera a resposta anterior do Hexagony , codificando os no-ops ( .) de uma maneira diferente. Embora essa resposta economize espaço ao transformar todos os outros caracteres em um ., o meu codifica o número de no-ops. Isso também significa que a fonte não precisa ser tão restrita.

Aqui eu uso uma codificação base 80, em que números abaixo de 16 indicam execuções de não operações, e números entre 16 e 79 representam o intervalo de 32 ( !) a 95 ( _) (agora só estou percebendo que joguei todos os _s do meu código lol). Algum pseudocódigo Pythonic:

i = absurdly long number
print(i)
base = 80
n = i%base
while n:
    if n < 16:
        print("."*(16-n))
    else:
        print(ASCII(n+16))
    i = i//base
    n = i%base

O número é codificado na primeira metade do hexágono, com todas as

" " > 
 " " > 
  ... etc

no lado esquerdo e o

 > ,
< "
 >
< "
... etc

no lado direito, redirecionando o ponteiro para codificar o número em uma célula. Isso foi retirado da resposta de Martin Ender (obrigado), porque não consegui descobrir uma maneira mais eficiente.

Em seguida, entra na seção inferior através do ->:

       " " > \ ' Q 4 ; = " / @ > . . . .
        . . . . . . . . . . . < " . . .
         . . " " > P = ' % < . > . . .
          . . . . . . . . . . < " . .
     ->    ! ' < . \ = 6 , ' / > . .

!imprime o número e 'navega para a célula de memória correta antes de iniciar o loop. P='%mods o número atual de 80. Se o resultado for 0, vá até a terminação @, então ir para baixo e criar uma célula ao lado do resultado da modificação com o valor -16.

   . " " > ' . . . . > + ' \ . > . . . . . .
    . . . = = . . . . . . . . < " . . . . .
     . " " > : > ) < $ = < . . > . . . . .
      . . . . . . . . . $ . . < " . . . .
       " " > \ ' Q 4 ; = " / @ > . . . .
                      /
                     /

Defina a célula como (valor mod + -16). Se esse valor for negativo, suba na ramificação >+'\, caso contrário, desça.

Se o valor for positivo:

 " " > . / < $ ; - < . . . . . > , . . . . . .
  . . . = = . . . . . . . . . < " . . . . . .
   . " " > ' . . . . > + ' \ . > . . . . . .

O ponteiro termina no ;-<que define a célula para (valor mod - -16) e a imprime.

O valor é negativo:

   . " " > ' . . . . > + ' \ . > . . . . . .
    . . . = = . . . . . . . . < " . . . . .
     . " " > : > ) < $ = < . . > . . . . .

Vá para a > ) <seção que inicia o loop. Aqui está isolado:

     . . > ) < $ = < . .
      . . . . . . . . .
       \ ' Q 4 ; = " /

Que executa o código 'Q4;="=que imprime um .(obrigado novamente a Martin Ender, que escreveu um programa para encontrar as combinações de números de letras para caracteres) e volta para a célula inicial. Em seguida, incrementa ( )) a célula de valor mod e faz um loop novamente, até que o valor mod seja positivo.

Quando isso é feito, ele se move para cima e se junta à outra seção em:

 " " > . / < $ ; - < . . .
            \
             \

O ponteiro volta para o início do loop maior novamente

 " " > . / <--
  . . . = =
   . " " > ' 
    . . . = = 
     . " " > :
      . . . . .
       " " > \ ' . .
        . . . . . . .
         . . " " > P = ' % < . > . . .

Isso executa, ='=:'que divide o número atual por 80 e navega para a célula correta.

Versão antiga (comprimento lateral 13)

343492224739614249922260393321622160373961419962223434213460086222642247615159528192623434203460066247203920342162343419346017616112622045226041621962343418346002622192616220391962343417346001406218603959366061583947623434"">/':=<$;'<.....>(......................<"......"">....'...>=\..>.....................<"....."">....>)<.-...>...........==......<"...."">.."...'.../>.................<"..."">\Q4;3=/.@.>...............<".."".>c)='%<..>..!'<.\1*='/.\""

Experimente online!

Definitivamente, posso jogar golfe de outro lado, mas vou ter que deixar amanhã até porque está ficando tarde. Acontece que estou impaciente e mal posso esperar até amanhã. Talvez outro lado possa ser jogado no golfe? :( ahhhhhhhhh eu fiz isso!

Até joguei dois dígitos extras com uma codificação básica 77, mas isso realmente não importa, já que tem o mesmo valor anterior.


13
Isso é incrível. A idéia para essa codificação híbrida de execução é realmente interessante. :) Lembre-me de lhe dar uma recompensa, se eu esquecer.
Martin Ender

35

PostScript, 20 caracteres

Curto e legítimo. 20 caracteres, incluindo nova linha à direita.

(dup == =)
dup == =

33

Cubix , 45 bytes

.....>...R$R....W..^".<R.!'.\)!'"R@>>o;?/o'u"

Você pode testar esse código aqui .

Esse programa é bastante difícil de acompanhar, mas para ter alguma chance de fazê-lo, precisamos começar expandindo-o para um cubo, como o intérprete Cubix:

      . . .
      . . >
      . . .
R $ R . . . . W . . ^ "
. < R . ! ' . \ ) ! ' "
R @ > > o ; ? / o ' u "
      . . .
      . . .
      . . .

Este é um quine no estilo Befunge, que funciona através da exploração de empacotamento para fazer com que os literais de string "envolvam" o código executável (com apenas uma "marca, o código fica dentro e fora da citação ao mesmo tempo, algo que se torna possível quando você tem programas não-lineares e não-planos). Observe que isso se encaixa em nossa definição de quine adequado, porque duas das aspas duplas não se codificam, mas são calculadas posteriormente através do uso de aritmética.

Ao contrário do Befunge, porém, estamos usando quatro strings aqui, em vez de um. Veja como eles são empurrados para a pilha;

  1. O programa inicia no topo da borda esquerda, indo para a direita; ele vira à direita duas vezes ( R), fazendo-o ir para a esquerda ao longo da terceira e última das linhas que envolvem o cubo inteiro. A aspas duplas corresponde a si mesma, então empurramos a terceira linha inteira para a pilha para trás. Em seguida, a execução continua após as aspas duplas.

  2. O ucomando faz uma inversão de marcha para a direita, então a próxima coisa que executamos é a partir '"da linha do meio. Isso empurra um "para a pilha. Continuando a contornar, atingimos o <lado esquerdo do cubo e nos recuperamos. Ao nos aproximarmos dessa direção, vemos um "comando simples , não '", então a segunda linha inteira é empurrada para a pilha para trás acima da terceira linha e entre aspas duplas.

  3. Começamos pressionando a !na pilha ( '!) e incrementando-a ( )); isso produz aspas duplas sem precisar de aspas duplas em nosso código-fonte (que terminaria a string). Um espelho ( \) reflete a direção da execução para o norte; então o Wcomando se afasta para a esquerda. Isso nos deixa subindo na sétima coluna, que, por ser um cubo, passa para a esquerda na terceira linha e depois para a terceira coluna. Apertamos um R, para virar à direita e seguir para a esquerda ao longo da linha superior; depois, $pula a Rvia pela qual entramos no programa, de modo que a execução se aproxima "do final da linha e capturamos a primeira linha em uma string da mesma maneira que fizemos na segunda e na terceira.

  4. O ^comando nos envia para o norte, subindo a décima primeira coluna, que é (permitindo o empacotamento do cubo) na direção sul, na quinta. A única coisa que encontramos lá !(pule se for diferente de zero; a parte superior da pilha é de fato diferente de zero), que pula o ocomando, efetivamente deixando a quinta coluna totalmente vazia. Então, voltamos ao ucomando, que mais uma vez dá meia-volta, mas dessa vez somos deixados na coluna final para o sul, que passa para a quarta coluna para o norte. Porém, atingimos uma citação dupla durante a inversão de marcha e capturamos a quarta coluna inteira em uma sequência, de baixo para cima. Diferentemente da maioria das aspas duplas no programa, essa não se fecha; em vez disso, é fechado "no canto superior direito, o que significa que capturamos a sequência de nove caracteres ...>......

Portanto, o layout da pilha é agora, de cima para baixo: quarta coluna; linha superior; "; linha do meio; "; linha inferior. Cada um deles é representado na pilha com o primeiro caractere mais próximo do topo da pilha (o Cubix pressiona as cordas no sentido inverso dessa ordem, como o Befunge, mas cada vez que o IP estava se movendo na direção oposta à direção natural da leitura, de modo que foi efetivamente revertido duas vezes). Pode-se notar que o conteúdo da pilha é quase idêntico ao programa original (porque a quarta coluna e a face norte / superior do cubo contêm os mesmos caracteres na mesma ordem; obviamente, ele foi projetado intencionalmente).

O próximo passo é imprimir o conteúdo da pilha. Depois de todos os empurrões, o IP está indo para o norte na quarta coluna, por isso atinge o >local e entra em um loop apertado >>o;?(ou seja, "vire para o leste, vire para o leste, faça a saída como caractere, pop, vire para a direita se positivo"). Como a sétima linha está cheia de NOPs, ela ?volta à primeira >, e isso empurra efetivamente todo o conteúdo da pilha (não ?é uma opção em uma pilha vazia). Quase imprimimos o programa inteiro! Infelizmente, ainda não está pronto; faltamos aspas duplas no final.

Quando o loop termina, refletimos na linha central, movendo-se para oeste, através de um par de espelhos. (Usamos o "outro lado" do \espelho anteriormente; agora estamos usando o lado sudoeste. O /espelho não foi usado antes.) Nos encontramos '!, então pressionamos um ponto de exclamação (ou seja, 33; estamos usando ASCII e o Cubix não faz distinção entre números inteiros e caracteres) na pilha. (Convenientemente, é o mesmo !que foi usado para pular o ocomando anteriormente.) Encontramos um par de Rcomandos e os usamos para fazer uma inversão de marcha "manual" (o segundo Rcomando aqui foi usado anteriormente para alcançar o primeiro linha, então parecia mais natural ajustar outro Rcomando ao lado dela.Wcomando, para desviar para a esquerda. O desvio contorna o >comando na segunda linha, devolvendo a execução exatamente onde estava. Então, desviaremos para a esquerda novamente, mas desta vez estamos indo para o sul, então o próximo comando a ser executado é o )(incrementando o ponto de exclamação em aspas duplas), seguido de um o(para produzi-lo). Por fim, a execução passa pela oitava linha até a segunda coluna, onde encontra um @para sair do programa.

Peço desculpas pelo apóstrofo perdido na terceira linha. Não faz nada nesta versão do programa; fazia parte de uma idéia anterior que eu tinha, mas que acabou não sendo necessária. No entanto, assim que obtive uma solução de trabalho, eu só queria enviá-la, em vez de mexer ainda mais, especialmente porque a remoção não alteraria a contagem de bytes. No que diz respeito ao golfe ainda mais, não me surpreenderia se isso fosse possível em 3 × 3 usando apenas as cinco primeiras linhas, mas não vejo uma maneira óbvia de fazer isso, e seria necessário empacotamento ainda mais apertado de todo o fluxo de controle, juntamente com alguma outra maneira de representar a face superior do cubo (ou modificar o algoritmo para que ele possa continuar usando a quarta coluna, mesmo que agora tenha dez ou onze caracteres) .


Bom trabalho, esta é uma pontuação realmente impressionante. Eu amo como você codificou a face superior. :)
Martin Ender

Isto é simplesmente incrível! Se isso ajudasse, outra maneira de empurrar "é Q.
ETHproductions

1
Uau! Eu nunca pensei que veria um cubix quine!
FlipTack

3
Ontem não tive tempo de ler a explicação, mas agora que tenho ... Apenas ... UAU. Não acredito quantos caracteres são usados ​​para dois ou até três propósitos completamente diferentes. Este é provavelmente o programa Cubix mais legal que eu já vi.
ETHproductions

Boa explicação.
Robert Fraser

33

Python 2, 30 bytes

_='_=%r;print _%%_';print _%_

Retirado daqui


1
+1, você venceu minha solução semelhante, então eu a apaguei. Deve-se notar que isso só funciona em Python 2.
nyuszika7h

2
Parece estranho com o nome da variável como _, mas fica melhor se você o atribuir a qualquer letra, ou seja, s:s='s=%r;print s%%s';print s%s
Ehtesh Choudhury

5
Se essa solução não for sua própria criação, você deve torná-la Wiki da Comunidade. Além disso, o link está morto.
precisa saber é o seguinte

1
Estou um pouco atrasado para a festa, mas alguém pode explicar como isso funciona?
MadTux 12/10

9
Isso requer que um avanço de linha à direita seja válido. Como é, o código fonte não corresponde à saída.
Dennis

32

Teclas Vim, 17 , 14

Alguém votou aleatoriamente nisso, então lembrei que ela existe. Quando reli, pensei: "Ei, posso fazer melhor que isso!", Então joguei dois bytes fora. Ainda não é o mais curto, mas pelo menos é uma melhoria.


Por um longo tempo, eu estive pensando se um vim quine é possível. Por um lado, deve ser possível, pois o vim está completo. Mas depois de procurar um vim quine por um tempo muito longo, não consegui encontrá-lo. Eu queria encontrar este desafio PPCG , mas ele está fechado e não quines exatamente sobre literais. Então eu decidi fazer um, já que não consegui encontrar um.

Estou realmente orgulhoso desta resposta, por causa de dois primeiros :

  1. Esta é a primeira pergunta que eu já fiz, e

  2. Até onde eu sei, esta é a primeira versão do mundo a ser publicada! Eu posso estar errado sobre isso, então se você souber de um, por favor me avise.

Então, após essa longa introdução, aqui está:

qqX"qpAq@q<esc>q@q

Experimente online!

Observe que quando você digitar isso, ele exibirá o <esc>pressionamento de tecla como ^[. Isso ainda é preciso, pois ^[representa 0x1B, o que é escape em ASCII , e a maneira como o vim representa internamente a <esc>chave.

Observe também que o teste disso poderá falhar se você carregar uma sessão vim existente. Eu escrevi uma resposta em explicando isso aqui , se você quiser mais informações, mas basicamente você precisa iniciar o vim com

vim -u NONE -N -i NONE

ou digite qqqantes de executar isso.

Explicação:

qq                  " Start recording into register 'q'
  X                 " Delete one character before the cursor (Once we play this back, it will delete the '@')
   "qp              " Paste register 'q'
      Aq@q<esc>     " Append 'q@q' to this line
               q    " Stop recording
                @q  " Playback register 'q'

Em uma nota lateral, esta resposta é provavelmente um recorde mundial para a maioria dos q's em uma resposta PPCG, ou algo assim.


1
2i2i<esc>está tão perto. Eu sinto que deve haver algo que eu possa fazer para fazer isso funcionar.
Zwei

@wei eu sei, está perto dói! Na verdade, <Esc>está implícito em V, então isso funciona . Infelizmente, também adiciona uma nova linha, e é por isso que ainda não a publiquei.
DJMcMayhem

q"iq"qbP<Esc>qbPé 11. Depois de colocar isso no reddit , eu investiguei o vimgolfing aqui e decidi fazer uma conta. Esta é a resposta que eu postei lá.
Udioica 11/10

2
@udioica Você pode postar isso como resposta?
DJMcMayhem

28

Perdido , 120 116 98 96 76 70 66 bytes

Edit: yay, abaixo de 100

Editar: salvou um monte de bytes alternando para todos os /s na linha inferior

:2+52*95*2+>::1?:[:[[[[@^%?>([ "
////////////////////////////////

Experimente online! + a verificação é determinística para todos os estados possíveis

Lost é uma linguagem 2D em que a posição inicial e a direção são completamente aleatórias. Isso significa que deve haver muita verificação de erros em todos os estágios para garantir que você tenha o ponteiro de instruções correto, e não é aquele que apenas apareceu aleatoriamente.

Explicação:

Todos os /s na linha inferior estão lá para garantir que todos os ponteiros que aparecem na direção vertical ou na linha inferior sejam canalizados na direção certa. A partir daí, eles acabam em vários lugares diferentes, mas todos acabam indo direto para o

 ^%?>
 ////

O que limpa todos os números diferentes de zero na pilha. O ([depois disso limpa quaisquer 0s extras também.

No meio da clareira, ele bate no %, que desliga a 'segurança', o que permite que o programa termine quando ele bate no @(sem isso, o programa pode terminar imediatamente se um ponteiro iniciar no @).

A partir daí, ele cria uma linguagem 2D bastante simples, envolvendo uma string literal ( ") na primeira linha, pressionando um "caractere enganando um space ( :2+) e depois uma nova linha ( 52*). Para a segunda linha, ele cria um /caractere ( 95*2+) e o duplica um monte ( >::1?:[:[[[[), antes de finalmente terminar na @e imprimir a pilha implicitamente. O ?1objetivo é impedir que o processo crie muitos 0s se o ponteiro entrar cedo, poupando a necessidade de limpá-los mais tarde.

Salvei 20 bytes aqui, criando a última linha com o mesmo caractere, o que significa que eu poderia ir direto do processo de dupagem para o final @.

Explicação sobre o processo de duping:

[é um personagem conhecido como 'Porta'. Se o ponteiro atingir o lado plano de a [ou a ], ele reflete, caso contrário, passa por ele. Cada vez que o ponteiro interage com uma porta, ele muda para o tipo oposto. Usando esse conhecimento, podemos construir uma fórmula simples para quantas vezes uma instrução será executada em um >:[bloco.

Adicione a quantidade inicial de instruções. Para cada um [, adicione duas vezes a quantidade de instruções à esquerda. Por exemplo >::::[:[[[, começamos com 5 como o valor inicial. A primeira porta tem 4 instruções duplas, então adicionamos 4 * 2 = 8 a 5 para obter 13. As outras três portas têm 5 duplas à esquerda, então adicionamos 3 * (5 * 2) = 30 a 13 para obter 43 instruções falsas executadas e possuem 44 >s na pilha. O mesmo processo pode ser aplicado a outras instruções, como (enviar uma grande quantidade de itens da pilha para o escopo, ou conforme usado aqui, para limpar itens da pilha.

Um truque que usei aqui para evitar enganar muitos 0s é o 1?. Se o caractere for 0, ?ele não ignora o 1, o que significa que ele duplica 1 pelo restante do dupe. Isso facilita muito a limpeza da pilha posteriormente.


25

Estes são os dois menores códigos de Ruby da SO :

_="_=%p;puts _%%_";puts _%_

e

puts <<2*2,2
puts <<2*2,2
2

Não me pergunte como o segundo funciona ...


8
O segundo usa o heredoc, <<2inicia uma sequência na próxima linha e *2repete a sequência
Ming-Tang

Por que você precisa dos 2?
CalculatorFeline

1
@CalculatorFeline É o terminador da string heredoc (que deve aparecer em sua própria linha). Na verdade, não tem que ser um 2 no entanto: tio.run/##KypNqvz/v6C0pFjBxsZAy0jHgAuFY8D1/z8A
Martin Ender

25

Fissão , 6 bytes

Parece que agora é o quine mais curto e "adequado" entre essas respostas.

'!+OR"

Explicação

O fluxo de controle começa Rcom um único (1,0)átomo à direita . Ele atinge o "modo de impressão alternado e, em seguida, envolve a linha, imprimindo '!+ORantes de "repetir o mesmo e sair do modo de impressão.

Isso deixa a "si próprio para ser impresso. O caminho mais curto é '"O(onde '"define a massa do átomo para o código de caractere "e Oimprime o caractere e destrói o átomo), mas se fizermos isso, isso "interferirá no modo de impressão. Então, em vez disso, definimos o valor do átomo como '!(um a menos que "), depois incrementamos com +e depois imprimimos o resultado com O.

Alternativas

Aqui estão algumas alternativas, que são mais longas, mas talvez suas técnicas inspirem alguém a encontrar uma versão mais curta usando-as (ou talvez elas sejam mais úteis em determinadas categorias generalizadas).

8 bytes usando Jump

' |R@JO"

Novamente, o código começa em R. Os @swaps de massa e energia para dar (0,1). Portanto, o Játomo pula sobre a Oreta para a ". Então, como antes, todos, exceto os, "são impressos no modo de sequência. Depois, o átomo bate |para inverter sua direção e passa pela '"Oimpressão ". O espaço é um pouco chato, mas parece necessário, porque, caso contrário ', o átomo faria o tratamento |como um personagem, em vez de um espelho.

8 bytes usando dois átomos

"'L;R@JO

Isso tem dois átomos, começando a partir da esquerda e indo da Ldireita R. O átomo à esquerda obtém seu valor definido pelo '"qual é imediatamente impresso com O(e o átomo é destruído). Para o átomo certo, trocamos massa e energia novamente, saltamos sobre o Opara imprimir o restante do código no modo de impressão. Posteriormente, seu valor é definido por, 'Lmas isso não importa, pois o átomo é descartado ;.


Tecnicamente inválido devido à falta de separação de código / dados na fonte.
CalculatorFeline

4
@CalculatorFeline '!+codifica ".
Martin Ender

Eu não estou familiarizado com Fission, mas |R@JO"'funcionaria, ou você ainda precisaria desse espaço após o '?
MildlyMilquetoast

1
@MistahFiggins Acho que sim, mas o mais importante é que você imprima o 'primeiro.
6137 Martin Ender #

24

JavaScript em vários navegadores (41 caracteres)

Ele funciona nos 5 principais navegadores da Web (IE> = 8, Mozilla Firefox, Google Chrome, Safari, Opera). Insira-o no console do desenvolvedor em qualquer um desses:

eval(I="'eval(I='+JSON.stringify(I)+')'")

Não é "trapaça" - ao contrário do quine de byte único de Chris Jester-Young, pois ele pode ser facilmente modificado para usar a alert()função (custando 14 caracteres):

alert(eval(I="'alert(eval(I='+JSON.stringify(I)+'))'"))

Ou convertido em um bookmarklet (custando 22 caracteres):

javascript:eval(I="'javascript:eval(I='+JSON.stringify(I)+')'")

24

C, 64 60 bytes

main(s){printf(s="main(s){printf(s=%c%s%1$c,34,s);}",34,s);}

Até agora, este é o C quine mais curto conhecido. Há uma recompensa estendida se você encontrar uma mais curta.

Isso funciona no GCC , Clang e TCC em um ambiente POSIX . Invoca uma quantidade excessiva de comportamento indefinido com todos eles.

Apenas por diversão, aqui está um repositório que contém todos os Cines que eu conheço. Sinta-se à vontade para fazer uma bifurcação / relações públicas se encontrar ou escrever uma outra que acrescente algo novo e criativo aos existentes.

Observe que ele funciona apenas em um ambiente ASCII . Isso funciona para o EBCDIC , mas ainda requer o POSIX . Boa sorte para encontrar um ambiente POSIX / EBCDIC de qualquer maneira: P


Como funciona:

  1. main(s)mainargumentos de abuso , declarando uma variável praticamente sem tipo s. (Observe que, sna verdade, não é digitado, mas, como os compiladores listados o convertem automaticamente conforme necessário, pode ser *.)
  2. printf(s="..."define sa string fornecida e passa o primeiro argumento para printf.
  3. sestá definido para main(s){printf(s=%c%s%1$c,34,s);}.
  4. A %cestá definida para ASCII 34, ". Isso torna a solução possível. Agora sse parece com isso:
    main(s){printf(s="%s%1$c,34,s);}.
  5. O %sé definido para ssi mesmo, o que é possível devido ao item 2. Agora sse parece com isso:
    main(s){printf(s="main(s){printf(s=%c%s%1$c,34,s);}%1$c,34,s);}.
  6. A %1$cestá definida para ASCII 34 ", printfda primeira ** argumento. Agora, sfica assim:
    main(s){printf(s="main(s){printf(s=%c%s%1$c,34,s);}",34,s);}
    ... que é o código fonte original.

* Exemplo graças ao primeiro argumento do @Pavel
** após o especificador de formato - neste caso s,. É impossível fazer referência ao especificador de formato.


Eu acho que é impossível que isso fique mais curto com a mesma abordagem. Se printfo especificador de formato estivesse acessível via $, isso funcionaria para 52 bytes:

main(){printf("main(){printf(%c%0$s%1$c,34);}",34);}

Embora certamente não deva ser considerado competitivo, o vencedor do "Pior abuso das regras" do Concurso Internacional de Código C Ofuscado de 1994, 1994_smr.c , é definitivamente mais curto.
Ray

@ Ray Não é permitido. Não é uma solução adequada para qualquer definição. As regras do quien foram alteradas por causa desse programa: P
MD XF

Eu concordo inteiramente, mas é um truque interessante o suficiente que vale a pena mencionar sempre que alguém menciona um menor quine conhecido, mesmo que por razões históricas.
Ray

4
sé do tipo int, não uma "variável não digitada".
feersum

2
Todos esses compiladores aparentemente permitem a conversão implícita de um ponteiro para um int. s=3obviamente não funcionaria porque você precisa passar a string duas vezes para printf.
22417 feersum

24

Java, 528 bytes:

Uma solução Java com uma abordagem original:

import java.math.*;class a{public static void main(String[]a){BigInteger b=new BigInteger("90ygts9hiey66o0uh2kqadro71r14x0ucr5v33k1pe27jqk7mywnd5m54uypfrnt6r8aks1g5e080mua80mgw3bybkp904cxfcf4whcz9ckkecz8kr3huuui5gbr27vpsw9vc0m36tadcg7uxsl8p9hfnphqgksttq1wlolm2c3he9fdd25v0gsqfcx9vl4002dil6a00bh7kqn0301cvq3ghdu7fhwf231r43aes2a6018svioyy0lz1gpm3ma5yrspbh2j85dhwdn5sem4d9nyswvx4wmx25ulwnd3drwatvbn6a4jb000gbh8e2lshp",36);int i=0;for(byte c:b.toByteArray()){if(++i==92)System.out.print(b.toString(36));System.out.print((char)c);}}}

na forma legível:

import java.math.*;
class a
{
    public static void main (String [] a)
    {
        BigInteger b=new BigInteger ("90ygts9hiey66o0uh2kqadro71r14x0ucr5v33k1pe27jqk7mywnd5m54uypfrnt6r8aks1g5e080mua80mgw3bybkp904cxfcf4whcz9ckkecz8kr3huuui5gbr27vpsw9vc0m36tadcg7uxsl8p9hfnphqgksttq1wlolm2c3he9fdd25v0gsqfcx9vl4002dil6a00bh7kqn0301cvq3ghdu7fhwf231r43aes2a6018svioyy0lz1gpm3ma5yrspbh2j85dhwdn5sem4d9nyswvx4wmx25ulwnd3drwatvbn6a4jb000gbh8e2lshp", 36); 
        int i=0; 
        for (byte c:b.toByteArray ())
        {
            if (++i==92) 
                System.out.print (b.toString (36)); 
            System.out.print ((char) c);
        }
    }
}

Como funciona?
Loovjo 23/05

1
@Loovjo: Semelhante a outras soluções que cortam o código em duas partes e inserem a String inteira que reprensenta o código novamente, mas o código inteiro não é apenas uma String, mas codificado como o número longo na base 36 (26 caracteres alfabéticos + 10 dígitos).
usuário desconhecido

1
Isto poderia ser reduzido se você colocar if(++i==92),
tuskiomi

2
@tuskiomi: Obrigado, reduzido para dois caracteres
usuário desconhecido

1
@userunknown Na verdade, a*como o array não sai em Java, esse é C. Algumas outras partes do golf :, import java.math.*;class a{public static void main(String[]a){BigInteger b=new BigInteger("abc",36);int i=0;for(int c:b.toByteArray())System.out.printf("%s%c",++i==92?b.toString(36):"",c);}}onde abcseria o número mágico recém-calculado String. Em java 8+ também é possível mudar class a{public static void mainpara interface a{static void main, e em Java 10 + também é possível mudar import java.math.*;e BigInteger b=new BigInteger(para var b=new java.math.BigInteger(.
Kevin Cruijssen 23/03

23

Frango , 7

chicken

Não, isso não é ecoado diretamente :)


Droga, você chegou antes de mim :)
Taconut

Não é ecoado, é a corda chicken!
Erik the Outgolfer

Nenhuma separação de código / dados e, portanto, inválida.
CalculatorFeline

10
@CalculatorFeline Você leu as regras?
Timtech 5/17

1
@JoKing Não acho que isso seja inválido, porque as regras do desafio proíbem quines de comprimento zero e trapaça (leitura do seu próprio arquivo de origem). A única coisa que proíbe quines impróprios é uma brecha padrão - exceto que brechas padrão não são geralmente consideradas aplicáveis ​​a respostas que os antecedem.
pppery

23

Retina , 20 14 9 7 bytes

Antes de começarmos, gostaria de mencionar a solução trivial de um arquivo que contém um único 0. Nesse caso, o Retina tentará contar os 0s na entrada vazia, cujo resultado também é 0. Eu não consideraria isso uma solução adequada.

Então, aqui está uma boa:

>\`
>\`

Experimente online!

Como alternativa, poderíamos usar em ;vez de >.

Explicação

O programa consiste em uma única substituição que imprimimos duas vezes.

Na primeira linha, o `separa a configuração do regex, portanto, o regex está vazio. Portanto, a cadeia vazia (ou seja, a entrada inexistente) é substituída pela segunda linha, literalmente.

Para imprimir o resultado duas vezes, envolvemos-o em dois estágios de saída. A interna, \imprime o resultado com um avanço de linha à direita, e a externa >, imprime sem um.

Se você está um pouco familiarizado com o Retina, pode estar se perguntando o que aconteceu com a saída implícita do Retina. A saída implícita da Retina funciona envolvendo o estágio final de um programa em um estágio de saída. No entanto, o Retina não faz isso, se o estágio final já é um estágio de saída. A razão para isso é que, em um programa normal, é mais útil substituir o estágio de saída implícito por um estágio especial \ou ;por um único byte (em vez de ter que se livrar do implícito com a .flag também). Infelizmente, esse comportamento acaba nos custando dois bytes para o quine.


20

Javascript (36 caracteres)

(function a(){alert("("+a+")()")})()

Este é, AFAICT, o quine javascript mais curto publicado até o momento.


1
Isso é impressionante. Você deve explicar como isso funciona para mim 8- |
TehShrike 27/09/11

3
@TehShrike Dica: você pode visualizar o conteúdo de uma função coagindo-a a uma string. Por exemplo, se você tiver uma função a, poderá acessar seu conteúdo chamando a.toString.
Peter Olson

7
Para ser pedante, porém, isso é apenas uma solução, se a implementação do JavaScript restringir a função aexatamente da mesma maneira que foi escrita acima. No entanto, é provável que a saída desse código seja uma solução para qualquer implementação de JavaScript.
Ilmari Karonen

1
Aqui é a mesma Quine, 1 byte mais curto: !function a(){alert("!"+a+"()")}().
Ismael Miguel

1
(a=()=>alert(($ {a})))()
Dennis C

19

GolfScript, 8 bytes

Eu sempre pensei que o menor (verdadeiro) quine do GolfScript fosse 9 bytes:

{'.~'}.~

Onde o avanço de linha à direita é necessário porque o GolfScript imprime um avanço de linha à direita por padrão.

Mas acabei de encontrar um quine de 8 bytes, que funciona exatamente em torno dessa restrição de avanço de linha:

":n`":n`

Experimente online!

Portanto, o problema é que o GolfScript não imprime um avanço de linha à direita, mas imprime o conteúdo nno final do programa. É apenas que ncontém um avanço de linha para começar. Portanto, a idéia é substituí-la pela string ":n`"e, em seguida, especificá-la, de modo que a cópia na pilha seja impressa com aspas e a cópia armazenada em nimpressões sem.

Conforme apontado por Thomas Kwa, o quine CJam de 7 bytes também pode ser adaptado a uma solução de 8 bytes:

".p"
.p

Novamente, precisamos do avanço de linha à direita.


6
Golfscript é estranho.
CalculatorFeline

19

Labirinto , 124 110 53 bytes

Graças ao Sp3000 por jogar 9 bytes, o que me permitiu jogar outros 7.

44660535853919556129637653276602333!
1
:_98
/8 %
@9_.

Experimente online!

Explicação

Labirinto 101:

  • Labirinto é uma linguagem 2D baseada em pilha. A pilha está sem fundo e cheia de zeros, portanto, saltar de uma pilha vazia não é um erro.
  • A execução começa a partir do primeiro caractere válido (aqui, no canto superior esquerdo). Em cada junção, onde há dois ou mais caminhos possíveis para o ponteiro de instrução (IP) seguir, a parte superior da pilha é verificada para determinar para onde ir a seguir. Negativo é virar à esquerda, zero é avançar e positivo é virar à direita.
  • Os dígitos no código-fonte não pressionam o número correspondente - em vez disso, eles aparecem no topo da pilha e pressionam n*10 + <digit>. Isso permite a fácil criação de grandes números. Para iniciar um novo número, use _, que empurra zero.
  • " são no-ops.

Primeiro, explicarei uma versão um pouco mais simples que é um byte mais longo, mas um pouco menos mágica:

395852936437949826992796242020587432!
"
:_96
/6 %
@9_.

Experimente online!

A idéia principal é codificar o corpo principal da fonte em um único número, usando uma base grande. Esse número pode ser facilmente impresso novamente antes de ser decodificado para imprimir o restante do código-fonte. A decodificação é simplesmente a aplicação repetida de divmod base, onde imprime mode continua trabalhando com o divaté zero.

Ao evitar {}, o código de caractere mais alto que precisamos é _(95), de modo que a base 96 seja suficiente (mantendo a base baixa, o número no início é mais curto). Então, o que queremos codificar é o seguinte:

!
"
:_96
/6 %
@9_.

Transformando esses caracteres em seus pontos de código e tratando o resultado como um número de base 96 (com o dígito menos significativo correspondente !e o mais significativo ., porque é a ordem na qual desmontaremos o número), obtemos

234785020242697299628949734639258593

Agora o código começa com um truque bem legal (se assim posso dizer) que nos permite imprimir de volta a codificação e manter outra cópia para decodificar com muito pouca sobrecarga: colocamos o número no código ao contrário. Eu calculei o resultado com esse script CJam. Então, vamos para o código real. Aqui está o começo:

395852936437949826992796242020587432!
"

O IP começa no canto superior esquerdo, indo para o leste. Enquanto passa sobre esses dígitos, simplesmente cria esse número no topo da pilha. O número em si não tem sentido, porque é o inverso do que queremos. Quando o IP atinge o !, ele apaga esse número da pilha e o imprime. É tudo o que há para reproduzir a codificação na saída.

Mas agora o IP atingiu um beco sem saída. Isso significa que ele se vira e agora volta para o oeste (sem executar !novamente). Desta vez, convenientemente, o IP lê o número de trás para a frente, de modo que agora o número no topo da pilha não codificar o restante da fonte.

Quando o IP agora atinge o canto superior esquerdo novamente, isso não é um beco sem saída, porque o IP pode virar à esquerda, então ele faz e agora se move para o sul. O "é um no-op, que precisamos aqui para separar o número do loop principal do código. Falando nisso:

...
"
:_96
/6 %
@9_.

Desde que a parte superior da pilha ainda não seja zero, o IP executará esse código bastante denso no seguinte loop:

"
>>>v
^< v
 ^<<

Ou dispostos linearmente:

:_96%._96/

O motivo para essas mudanças é por causa da semântica do fluxo de controle do Labyrinth. Quando houver pelo menos três vizinhos na célula atual, o IP vira à esquerda em um valor negativo da pilha, avança em zero e vira à direita em um valor positivo da pilha. Se a direção escolhida não for possível porque existe uma parede, o IP seguirá a direção oposta (razão pela qual existem duas curvas à esquerda no código, embora a parte superior da pilha nunca seja negativa).

O código do loop em si é realmente bastante direto (compactá-lo dessa maneira não era e é onde está a principal contribuição do Sp3000):

:    # Duplicate the remaining encoding number N.
_96  # Push 96, the base.
%.   # Take modulo and print as a character.
_96  # Push 96 again.
/    # Divide N by 96 to move to the next digit.

Quando Nchegar a zero, o fluxo de controle muda. Agora, o IP gostaria de seguir em frente depois do /(ou seja, oeste), mas há um muro lá. Então, ao invés, se virar (leste), executa 6novamente. Isso torna o topo da pilha positivo, de modo que o IP vire à direita (sul) e execute o 9. O topo da pilha é agora 69, mas tudo o que importa é que seja positivo. O IP faz outra curva à direita (oeste) e passa para a @que termina o código.

Em suma, bastante simples, na verdade.

Ok, agora como eliminamos esse byte adicional. Claramente, esse no-op parece um desperdício, mas precisamos dessa linha adicional: se o loop fosse adjacente ao número, o IP já seria movido para lá imediatamente, em vez de atravessar o número inteiro. Então, podemos fazer algo útil com essa não operação.

Bem, em princípio, podemos usar isso para adicionar o último dígito na codificação. A codificação realmente não precisa estar toda na primeira linha ... !apenas garante que o que estiver lá também seja impresso lá.

Há um problema, porém, não podemos fazer isso:

95852936437949826992796242020587432!
3
:_96
/6 %
@9_.

O problema é que agora alteramos o "para a 3, o que também altera o número real que queremos ter. E com certeza esse número não termina 3. Como o número é completamente determinado pelo código a partir de !, não podemos fazer muito sobre isso.

Mas talvez possamos escolher outro dígito? Realmente não nos importamos se há um 3nesse local, desde que terminemos com um número que codifica corretamente a fonte. Infelizmente, nenhum dos 10 dígitos produz uma codificação cujo dígito menos significativo corresponde ao escolhido. Felizmente, há alguma margem de manobra no restante do código para que possamos tentar mais algumas codificações sem aumentar a contagem de bytes. Encontrei três opções:

  1. Nós podemos mudar @para /. Nesse caso, podemos usar qualquer dígito 1357e obter uma codificação correspondente. No entanto, isso significa que o programa termina com um erro, o que é permitido, mas não parece muito limpo.
  2. Os espaços não são os únicos caracteres "parede". Todo caractere não utilizado é, notadamente, todas as letras. Se usarmos uma letra maiúscula, nem precisamos aumentar a base para acomodá-la (já que esses pontos de código estão abaixo _). 26 escolhas oferecem muitas possibilidades. Por exemplo, para Aqualquer dígito ímpar trabalha. Isso é um pouco melhor, mas ainda não parece tão elegante, pois você nunca usaria uma letra no código real.
  3. Nós podemos usar uma base maior. Enquanto não aumentarmos significativamente a base, o número de dígitos decimais na codificação permanecerá o mesmo (especificamente, qualquer base de até 104 está correta, embora bases acima de 99 realmente exijam caracteres adicionais no próprio código). Felizmente, a base 98 fornece uma única solução correspondente: quando usamos o dígito 1, a codificação também termina 1. Esta é a única solução entre as bases 96, 97, 98, 99, portanto, isso é realmente muita sorte. E é assim que terminamos com o código na parte superior desta resposta.

19

Perdido , 293 262 249 bytes

>:2+52*:6*:(84*+75*):>:::::[[[[[[[:[(52*)>::::[[[[[[:[84*+@>%?!<((((((((((([[[[[[[[[[[[[[ "
\#<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\

Experimente online!

Explicação

Todo esse projeto foi de alto a baixo. Continuei pensando que era impossível e depois tive uma ideia maluca que poderia funcionar.

Por que um Lost Quine é tão difícil?

Como você deve saber, Lost é uma linguagem de programação 2D em que o local e a direção de partida são inteiramente aleatórios. Isso torna a gravação de qualquer programa perdido tão difícil quanto a gravação de códigos protegidos por radiação. Você deve considerar todos os locais e direções possíveis.

Dito isto, existem algumas maneiras padrão de fazer as coisas. Por exemplo, aqui está a maneira padrão de imprimir uma string.

>%?"Stringv"(@
^<<<<<<<<<<<<<

Isso tem um fluxo de coleta na parte inferior que captura a maioria dos ips e os puxa para o local inicial. Quando eles alcançam o local de início (superior esquerdo), nós os higienizamos com um loop, eliminando todos os valores da pilha e, em seguida, vira a segurança de empurrar a corda e sair. (segurança é um conceito exclusivo de Lost, todo programa deve ser pressionado %antes de sair, isso evita a possibilidade de o programa terminar no início). Agora, minha idéia seria estender esse formulário para uma solução completa.

A primeira coisa a ser feita foi refazer um pouco o loop, o loop existente era específico para o formato String.

>%?!<"Stringv"(@
^<<<<<<<<<<<<<<<
^<<<<<<<<<<<<<<<

Precisamos adicionar um segundo fluxo para evitar a possibilidade de !pular sobre o fluxo e criar um loop.

Agora queremos misturar isso com o formato Quine padrão. Como Lost se baseia muito em Klein, eu basicamente roubei emprestado o Klien Quine para Martin Ender .

:2+@>%?!< "
<<<<^<<<<<<
<<<<^<<<<<<

Isso convenientemente imprime a primeira linha do quine. Agora, tudo o que precisamos fazer é codificar os fluxos. Bem, isso é mais fácil dizer do que fazer. Eu tentei aproximadamente quatro métodos diferentes de fazer isso. Vou apenas descrever o que funcionou.

A idéia aqui é usar portas para obter o número desejado de setas. Uma porta é um tipo especial de espelho que muda sempre que é atingido. [reflete ips vindos da esquerda e ]da direita. Quando eles são atingidos por um ip de um desses lados, a orientação do comutador. Podemos fazer uma linha dessas portas e um refletor estático para executar repetidamente uma operação.

>:[[[

Realizará :três vezes. Dessa forma, se empurrarmos um <para a pilha antes da mão, podemos fazer muitos deles com menos bytes. Fazemos 2 deles, um para cada linha, e entre eles estabelecemos uma nova linha; no entanto, o segundo só precisa ir até que cubra o !que adicionamos, qualquer coisa pode ser deixada em branco, economizando alguns bytes. Ok, agora precisamos adicionar as setas verticais aos nossos fluxos. É aqui que entra a otimização da chave. Em vez de redirecionar todos os ips para o "início" do programa diretamente, eles serão redirecionados para a extrema esquerda, porque já sabemos que os ips que começam na extrema esquerda devemtrabalho (ou pelo menos funcionará na versão final), também podemos apenas redirecionar os outros ips. Isso não apenas torna mais barato em bytes, acho que essa otimização é o que torna a solução possível.

No entanto, ainda existem alguns problemas, sendo o mais importante o ips, iniciado após o >envio, mas antes de começarmos a fazer cópias dele. Esses ips entrarão na copiadora e farão um monte de cópias de 0. Isso é ruim porque nosso mecanismo de limpeza de pilha usa zeros para determinar a parte inferior da pilha, deixando um monte de zeros na parte inferior. Precisamos adicionar um método mais forte de limpeza de pilhas. Como não há uma maneira real de saber se a pilha está vazia, teremos de tentar destruir o maior número possível de itens na pilha. Aqui, mais uma vez, usaremos o método da porta descrito anteriormente. Nós adicionaremos ((((((((((([[[[[[[[[[[[[[ao final da primeira linha logo após o higienizador para eliminar os zeros.

Agora, há mais um problema, já que redirecionamos nossos fluxos para os ips superiores esquerdos, começando no %e descendo já terá desligado a segurança e sairá prematuramente. Então, precisamos desativar a segurança. Fazemos isso adicionando um #ao fluxo, dessa forma, os ips que fluem pelo fluxo serão desativados, mas os ips que já foram higienizados não serão. Também #deve ser codificado na primeira linha.

É isso, espero que você entenda como isso funciona agora.


: / Tantos erros de digitação e elos perdidos
ASCII-only

17

YUP , 1165 879 606 561 540 522 498 + 7 = 505 bytes

Requer o -cheatsinalizador para permitir a definição de aliases.

022222120211111102222122021121202222212021112202222110222212202112110222221202122212022222102222212021222120222221022222102222210222221202222110222211022222210222221022222210222212202222221022221102211110222221022221220222212202112120221111022212202211210222212022222102211120222122022111202222120212212021221202222221022111102221210222122022222102222120212212022221102211110222122022221102222120212212022112120221111022212202112120222212=%;0e-=<;0<-=>;:0~--=1;1>=2;0%{{>0<~{~>~<<}>>>]}>]}${<#}%{@}

Experimente online!

Explicação

Existem duas partes para isso (como na maioria dos quines). Os dados:

022222120211111102222122021121202222212021112202222110222212202112110222221202122212022222102222212021222120222221022222102222210222221202222110222211022222210222221022222210222212202222221022221102211110222221022221220222212202112120221111022212202211210222212022222102211120222122022111202222120212212021221202222221022111102221210222122022222102222120212212022221102211110222122022221102222120212212022112120221111022212202112120222212

E o decodificador:

=%;0e-=<;0<-=>;:0~--=1;1>=2;0%{{>0<~{~>~<<}>>>]}>]}${<#}%{@}

Os dados são apenas uma codificação binária do decodificador (ou melhor, seu reverso). Cada 0começa um novo personagem e os 1s e 2s são 0- e 1-bits, respectivamente.

Observe que 0é um comando Yup padrão que empurra um zero, enquanto 1e 2não está definido neste momento. No entanto, atribuímos toda a parte dos dados ao comando %para que o 1e 2possa permanecer indefinido até que %seja realmente usado.

Em seguida, definimos mais alguns comandos:

0e-=<;
0<-=>;
:0~--=1;
1>=2;

<diminui o topo da pilha, >aumenta-o. 1(de maneira não intuitiva) dobra a parte superior da pilha. 2dobra e depois incrementa. Graças a essas definições, algo como 0221111, na verdade, deixará um 48 (110000 em binário) na pilha.

Os 32 bytes restantes fazem a decodificação real em duas partes. Primeiro, precisamos reconstruir a sequência de dados.

0%                ` Push a zero and then the data.
{                 ` For each value...
  {               `   Until that value is zero...
    >0<~{~>~<<}>  `   divmod 2. The div is the input to the next iteration,
                  `   the mod gives us the next bit.
    >>]           `   Increment twice (gives 2 or 3) and put at the bottom
                  `   of the stack.
  }
  >]              ` Increment the 0 and put it at the bottom as well.
}
$                 ` Reverse the entire stack.
{<#}              ` Decrement and print each number.

E, finalmente, pressionamos os dados novamente e imprimimos cada valor como um caractere:

%{@}

Para referência futura, aqui está um script CJam para codificar os dados.


17

Fueue , 423 bytes

Fueue é um esolang baseado em fila no qual o programa em execução é a fila.

)$$4255%%1(~):[)$$24%%0:<[~:)~)]~[$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]](H-):~:[)[):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]~:](106328966328112328136317639696111819119696281563139628116326221310190661962811611211962861109696289611619628116111612896281115421063633063961111116163963011632811111819159628151213262722151522061361613096119619190661966311961128966130281807072220060611612811961019070723232022060611

Experimente online!

Como funciona

Esta explicação pode ou não ter saído do controle. Por outro lado, não sei como explicar isso de maneira muito mais curta, de maneira que espero que as pessoas possam seguir.

Folha de dicas para Fueue

Consulte o artigo wiki da esolang para obter detalhes, incluindo os poucos recursos não utilizados neste programa.

  • O programa inicial é o estado inicial da fila, que pode conter os seguintes elementos:

    • Literais inteiros (somente não negativos na fonte, mas negativos podem ser calculados), executá-los imprime um caractere.
    • Blocos aninhados delimitados por colchetes, inertes (preservados intactos, a menos que alguma função atue sobre eles).
    • Funções, seus argumentos são os elementos que os seguem imediatamente na fila:
      • +*/-%: aritmético inteiro ( -é unário, %negação lógica). Inertes se não forem fornecidos argumentos numéricos.
      • ()<: coloque o elemento entre colchetes, remova os colchetes do bloco e adicione o elemento final ao bloco. Os dois últimos são inertes, a menos que sejam seguidos por um bloco.
      • ~:: troca, duplicado.
      • $: copiar (leva número + elemento). Inerte antes do não número.
      • H: interromper o programa.

    Note que enquanto []ninho, ()não - estas últimas são simplesmente funções separadas.

Sintaxe de rastreamento de execução

O espaço em branco é opcional no Fueue, exceto entre números. Nos seguintes rastreamentos de execução, será usado para sugerir a estrutura do programa, em particular:

  • Quando uma função é executada, ela e seus argumentos são destacados dos elementos circundantes com espaços. Se alguns dos argumentos forem complicados, também pode haver um espaço entre eles.
  • Muitos rastreamentos de execução são divididos em um "blob de atraso" à esquerda, separado de uma parte à direita que faz a manipulação substancial de dados. Veja a próxima seção.

Os colchetes {}(não usados ​​no Fueue) são usados ​​nos rastreamentos para representar o resultado inteiro de expressões matemáticas. Isso inclui números negativos, pois o Fueue possui apenas literais não negativos - -é a função de negação.

Vários nomes meta-variáveis ​​e ...são usados ​​para denotar valores e abreviações.

Táticas de atraso

Intuitivamente, a execução percorre a fila, modificando parcialmente o que ela passa. Os resultados de uma função não podem ser acionados novamente até o próximo ciclo. Diferentes partes do programa evoluem efetivamente em paralelo, desde que não interajam.

Como resultado, grande parte do código é dedicada à sincronização, em particular para atrasar a execução de partes do programa até o momento certo. Existem muitas opções para jogar golfe, o que tende a transformar essas partes em blobs ilegíveis que só podem ser entendidos rastreando seu ciclo de execução por ciclo.

Essas táticas nem sempre serão mencionadas individualmente no abaixo:

  • )[A]atrasos Apara um ciclo. (Provavelmente, o método mais fácil e mais legível.)
  • ~eftroca os elementos ee ftambém atrasa sua execução. (Provavelmente o menos legível, mas geralmente o mais curto para pequenos atrasos.)
  • $1eatrasa um único elemento e.
  • -e %são úteis para atrasar números (este último para 0e 1.)
  • Ao atrasar vários elementos iguais em uma linha, :ou $pode ser usado para criá-los a partir de um único.
  • (nenvoltórios nentre parênteses, que podem ser removidos posteriormente por conveniência. Isso é particularmente vital para cálculos numéricos, já que os números são instáveis ​​demais para serem copiados sem antes colocá-los em um bloco.

Estrutura geral

O restante da explicação é dividido em sete partes, cada uma para uma seção do programa em execução. Os ciclos maiores, após os quais a maioria deles se repete, serão chamados de "iterações" para distingui-los dos "ciclos" de passagens únicas por toda a fila.

Aqui está como o programa inicial é dividido entre eles:

A:  )$$4255%%1(~
B:  ):[)$$24%%0:<[~:)~)]~[$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]
C:  
D:  (H-
E:  
F:  
G:  ):~:[)[):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]~:](106328966328112328136317639696111819119696281563139628116326221310190661962811611211962861109696289611619628116111612896281115421063633063961111116163963011632811111819159628151213262722151522061361613096119619190661966311961128966130281807072220060611612811961019070723232022060611

O grande número no final do programa codifica o restante na ordem inversa, dois dígitos por caractere, com 30 subtraídos de cada valor ASCII (por exemplo, 10codifica a (.)

Em um nível superior, você pode pensar nos dados deste programa (começando com o bignum) como fluindo da direita para a esquerda, mas controlando a fluência da esquerda para a direita. No entanto, em um nível inferior, o Fueue atrapalha a distinção entre código e dados o tempo todo.

  • A Seção G decodifica o bignum em dígitos ASCII (por exemplo, dígito 0como número inteiro 48), dividindo primeiro os dígitos menos significativos. Produz um dígito a cada 15 ciclos.
  • A seção F contém os valores ASCII de dígitos produzidos (cada um dentro de um bloco) até que a seção E possa consumi-los.
  • A Seção E lida com os dígitos produzidos dois de cada vez, combinando-os em blocos do formulário [x[y]], imprimindo também o caractere codificado de cada par.
  • A Seção D consiste em um bloco profundamente aninhado, gradualmente construído a partir dos [x[y]]blocos, de forma que, uma vez que contenha todos os dígitos, ele possa ser executado para imprimir todos eles e interromper o programa inteiro.
  • A seção C lida com a construção da seção D e também recria a seção E.
  • A seção B recria a seção C e a si mesma a cada 30 ciclos.
  • A seção A faz uma contagem regressiva dos ciclos até a última iteração das outras seções. Em seguida, aborta a seção B e executa a seção D.

Seção a

A seção A lida com a programação do final do programa. São necessários 4258 ciclos para reduzir a uma única função de troca ~, que faz um ajuste na seção B que interrompe seu loop principal e inicia a execução da seção D.

)$ $4255% %1 (~
)$%%%...%% %0 [~]
)$%%%...% %1 [~]
⋮
)$ %0 [~]
) $1[~]
)[~]
~
  • Uma $função cria 4255 cópias do seguinte, %enquanto a (coloca ~entre colchetes.
  • Cada ciclo o último %é usado para alternar o seguinte número entre 0e 1.
  • Quando todos os %s são usados, ele $1cria 1 cópia do [~](efetivamente um NOP) e, no próximo ciclo, )remove os colchetes.

Seção B

A Seção B lida com a regeneração, bem como uma nova iteração da seção C a cada 30 ciclos.

) : [)$$24%%0:<[~:)~)]~[$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]
) [)$$24%%0:<[~:)~)]~[$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]            [BkB]
)$ $24%     %0  :<  [~:)~)]    ~ [$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<] [BkB]
)$ %...%%% %1   < < [~:)~)] [BkB]   [$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]
)$ %...%% %0      < [~:)~)[BkB]] [$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]
)$ %...% %1         [~:)~)[BkB][$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]
⋮
) $1 [~:)~)[BkB][$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]
) [~:)~)[BkB][$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]                    (1)
~:) ~)[BkB]                 [$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]
) : [BkB]                 ) [$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]      (2)
) [BkB] [BkB]               $11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<
  • A :duplica o bloco grande a seguir (uma cópia abreviada como [BkB]) e )remove os colchetes da primeira cópia.
  • $$24%%0 configura uma contagem regressiva semelhante à da seção A.
  • Enquanto isso conta, :<se transforma <<e ~troca dois dos blocos, colocando o código para uma nova seção C por último.
  • As duas <funções agrupam os dois blocos finais no primeiro - isso é redundante nas iterações normais, mas permitirá que a ~seção A faça seu trabalho no final.
  • (1) Quando a contagem regressiva termina, os )colchetes externos são removidos. Em seguida, ~:)vira ):e ~)troca a )para o início do código da seção C.
  • (2) A Seção B agora está de volta ao seu ciclo inicial, enquanto a )está prestes a remover os colchetes para começar a executar uma nova iteração da seção C.

Na iteração final, a ~seção A aparece no ponto (1) acima:

~ ) [~:)~)[BkB][$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]                  (1)
[~:)~)[BkB][$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]              )

O ~swaps )atravessa o bloco e entra na seção C, impedindo que a seção B seja executada novamente.

Seção C

A Seção C trata da fusão de novos pares de caracteres de dígitos no bloco da seção D e também da criação de novas iterações da seção E.

O abaixo mostra uma iteração típica com xe yrepresentando os códigos ASCII dos dígitos. Na primeira iteração, os elementos "D" e "E" recebidos são os iniciais [H]e -, em vez disso, como nenhuma seção anterior E foi executada para produzir pares de caracteres de dígitos.

C                                               D             E
$11~ )  ~<[[+$4--498+*-:~-10)):])<~]  [)))~]  < [)))~[...]]   [x[y]]
~~~ ~~~ ~~~ ~~) [[+$4--498+*-:~-10)):])<~]  < [)))~] [)))~[...][x[y]]]
~~~ ~~~     )  ~ [[+$4--498+*-:~-10)):])<~] [)))~[)))~[...][x[y]]]]
~~~       ~ )   [)))~[....]]                                  [[+$4--498+*-:~-10)):])<~]
                                              ~~[)))~[....]] )[[+$4--498+*-:~-10)):])<~]
                                                [)))~[....]]  ~[+$4--498+*-:~-10)):])<~
  • Isso usa um método diferente de sincronização que eu descobri para esta resposta. Quando você tem várias funções de troca ~em uma linha, a linha diminui para aproximadamente 2/3 de cada ciclo (porque um ~troca dois a seguir), mas ocasionalmente com um restante de ~s que causa danos manipula cuidadosamente o que se segue.
  • $11~produz essa linha. O próximo ~troca um <pelo bloco a seguir. Outro <no final anexa um novo bloco de pares de dígitos (dígitos x e y como códigos ASCII) ao bloco da seção D.
  • No próximo ciclo, a ~linha tem um ~~restante, que troca um ao ~longo do seguinte ). O outro <anexa a seção D a um [)))~]bloco.
  • Em seguida, o ~próprio swap trocou o seguinte bloco com o novo código da seção E no bloco da seção D. Em seguida, uma nova sobra ~troca uma )e, finalmente, a última ~~da ~linha troca uma delas pela seção E, assim como a chave )foi removida.

Na iteração final, as seções A ~trocaram um )entre a seção B e a seção C. No entanto, a seção C é tão curta que já desapareceu e )termina no início da seção D.

Seção D

A seção D trata da impressão do grande número final e da interrupção do programa. Durante a maior parte da execução do programa, é um bloco inerte que as seções B – G cooperam na construção.

    (H -
    [H]-
    ⋮
    [)))~[H-]]                  After one iteration of section C
    ⋮
    [)))~[)))~[H-][49[49]]]]    Second iteration, after E has also run
    ⋮
)   [)))~[...]]     [49[48]]    Final printing starts as ) is swapped in
    ))) ~[...][49[48]]
    )) )[49[48]] [...]
    )) 49 [48][...]             Print first 1
    ) )[48] [...]
    ) 48 [...]                  Print 0
    )[...]                      Recurse to inner block
    ...
    ⋮
    )[H-]                       Innermost block reached
    H -                         Program halts
  • No primeiro ciclo do programa, a (envolve a função de parada Hentre colchetes. A -seguir, ele será usado como um elemento fictício para a primeira iteração, em vez de um par de dígitos.
  • O primeiro par de dígitos reais incorporado é [49[49]]correspondente à final 11do numeral.
  • O último par de dígitos [49[48]](correspondente ao 10início do número) não é realmente incorporado ao bloco, mas isso não faz diferença )[A[B]]e )[A][B]é equivalente, ambos se transformando em A[B].

Após a iteração final, o )trocado para a direita da seção B chega e o bloco da seção D é desbloqueado. O )))~início de cada sub-bloco garante que todas as partes sejam executadas na ordem correta. Finalmente, o bloco mais interno contém a Hinterrupção do programa.

Seção E

A Seção E lida com a combinação de pares de dígitos ASCII produzidos pela seção G, e ambos imprimem o caractere codificado correspondente e enviam um bloco com o par combinado à esquerda para as seções C e D.

Novamente, o abaixo mostra uma iteração típica com xe yrepresentando os códigos ASCII dos dígitos.

E                                                   F
~ [+$4--498+*-:~-10)):] )              <  ~         [y] [x]
) [+$4--498+*-:~-10)):]                   < [x] [y]
+ $4-  - 498  +*- :~ -10 ) )              : [x[y]]
+---  -{-498} +*- ~~{-10} )       ) [x[y]]  [x[y]]
+--    - 498  +*   -{-10}       ~ ) x  [y]  [x[y]]
+-    -{-498} +               * 10 x  )[y]  [x[y]]
+      - 498                    + {10*x} y  [x[y]]
                         + {-498} {10*x+y}  [x[y]]
{10*x+y-498}  [x[y]]
[x[y]]
  • Os blocos de dígitos recebidos são trocados, o bloco y é anexado ao bloco x e todo o bloco de pares é copiado. Uma cópia será deixada até o final das seções C e D.
  • A outra cópia é desbloqueada novamente e, em seguida, uma sequência de funções aritméticas é aplicada para calcular 10*x+y-498o valor ASCII do caractere codificado. 498 = 10*48+48-30, 48desfaz a codificação ASCII de xe yenquanto 30muda a codificação de 00–99para para 30–129, o que inclui todos os ASCII imprimíveis.
  • O número resultante é então deixado para executar, que imprime seu caractere.

Seção F

A seção F consiste em blocos inertes contendo códigos de dígitos ASCII. Para a maior parte do programa executado, haverá no máximo dois aqui, pois a seção E os consome na mesma velocidade que G os produz. No entanto, na fase final de impressão, alguns 0dígitos redundantes serão coletados aqui.

[y] [x] ...

Seção G

A Seção G lida com a divisão do grande número no final do programa, primeiro com os dígitos menos significativos, e com o envio de blocos com seus códigos ASCII para as demais seções.

Como não tem verificação de parada, ele continuará produzindo 0dígitos quando o número for reduzido a 0, até que a seção D interrompa o programa inteiro com a Hfunção.

[BkG] abrevia uma cópia do grande bloco de código inicial, que é usado para auto-replicação para iniciar novas iterações.

Inicialização nos primeiros ciclos:

) :~  : [)[):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]~:]  ( 106328966328112328136317639696111819119696281563139628116326221310190661962811611211962861109696289611619628116111612896281115421063633063961111116163963011632811111819159628151213262722151522061361613096119619190661966311961128966130281807072220060611612811961019070723232022060611
)  ~ ~ [)[):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]~:]  [BkG] [10...11]
) [)[):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]~:]     ~ [BkG] [10...11]
) [):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]       ~ : [10...11]  [BkG]

A iteração típica Nindica o número a ser dividido:

) [):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]        ~ : [N]  [BkG]
) :~ [)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+ :5 )         : [N]  : [BkG]
)  ~ ~ [)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]  +5 5     ) [N]  [N] [BkG] [BkG]
) [)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]               ~ 10 N  [N] [BkG] [BkG]
) ~:~  ~ ( [:~)*[):~[$1(+48]):~+]-:~~)10)~~]               / N 10  [N] [BkG] [BkG]
)  ~ : [:~)*[):~[$1(+48]):~+]-:~~)10)~~]                 ( {N/10}  [N] [BkG] [BkG]
) [:~)*[):~[$1(+48]):~+]-:~~)10)~~]                    : [{N/10}]  [N] [BkG] [BkG]
:~ )*[):~[$1(+48]):~+]- :~ ~)10 )           ~ ~ [{N/10}]  [{N/10}] [N] [BkG] [BkG]
~~) *[):~[$1(+48]):~+]- ~~10 )             ) [{N/10}]  ~ [{N/10}] [N]  [BkG] [BkG]
)  ~ * [):~[$1(+48]):~+]  -10            ~ ) {N/10}  [N] [{N/10}] [BkG] [BkG]
) [):~[$1(+48]):~+]               * {-10} {N/10}  ) [N]  [{N/10}] [BkG] [BkG]
) :~ [$1(+48]) :~                 + {-10*(N/10)} N  [{N/10}] [BkG] [BkG]
)  ~ ~ [$1(+48]  )                 ~ ~ {N%10}  [{N/10}] [BkG] [BkG]
) [$1(+48]                 ~ ) {N%10}  ~ [{N/10}] [BkG]  [BkG]
$1(                     + 48 {N%10}    ) [BkG]  [{N/10}] [BkG]
                        ( {48+N%10}   BkG [{N/10}] [BkG]            New iteration starts
                        [{48+N%10}]   ....
  • O atraso aqui é particularmente cabeludo. No entanto, o único novo truque de atraso é usar em +:5vez de --10atrasar 10dois ciclos. Infelizmente, apenas um dos 10s no programa foi ajudado por isso.
  • Os blocos [N]e [BkG]são duplicados e, em seguida, uma cópia Né dividida por 10.
  • [{N/10}]é duplicado, mais funções aritméticas são usadas para calcular o código ASCII do último dígito de Nas 48+((-10)*(N/10)+N). O bloco com este código ASCII é deixado para a seção F.
  • A outra cópia de [{N/10}]é trocada entre os [BkG]blocos para configurar o início de uma nova iteração.

Quine de bônus (540 bytes)

)$$3371%%1[~!~~!)!]):[)$$20%%0[):]~)~~[)$$12%%0[<$$7%~~0):~[+----48+*-~~10))]<]<~!:~)~~[40~[:~))~:~[)~(~~/[+--48):]~10]+30])):]]][)[H]](11(06(06(21(21(25(19(07(07(19(61(96(03(96(96(03(11(03(63(11(28(61(11(06(06(20(18(07(07(18(61(11(28(63(96(11(96(96(61(11(06(06(19(20(07(07(18(61(30(06(06(25(07(96(96(18(11(28(96(61(13(15(15(15(15(22(26(13(12(15(96(96(19(18(11(11(63(30(63(30(96(03(28(96(11(96(96(61(22(18(96(61(28(96(11(11(96(28(96(61(11(96(10(96(96(17(61(13(15(15(22(26(11(28(63(96(19(18(63(13(21(18(63(11(11(28(63(63(63(61(11(61(42(63(63

Experimente online!

Como não tinha certeza de qual método seria o mais curto, tentei codificar caracteres como números de dois dígitos separados por (s. O código principal é um pouco menor, mas a representação de dados 50% maior o compensa. Não é tão jogado como o outro, pois parei quando percebi que não venceria. Ele tem uma vantagem: não requer uma implementação com suporte a bignum.

Sua estrutura geral é um pouco semelhante à principal. A seção G está ausente, pois a representação de dados preenche a seção F diretamente. No entanto, a seção E deve fazer um cálculo divmod semelhante para reconstruir os dígitos dos números de dois dígitos.


1
Você deve jogar a explicação XD
VFDan

1
)$n[)](é um byte mais curto para o contador de atraso.
jimmy23013

15

Geléia, 3 bytes

”ṘṘ

Experimente online!

Verificação

$ echo $LANG
en_US
$ xxd -g 1 quine.jelly
0000000: ff cc cc                                         ...
$ ./jelly f quine.jelly | xxd -g 1
0000000: ff cc cc                                         ...

Como funciona

”ṘṘ    Main link. No input.

”Ṙ     Set the return value to the character 'Ṙ'.
  Ṙ    Print a string representation of the return value.
       This prints: ”Ṙ
       (implicit) Print the return value.
       This prints: Ṙ

Qual versão do intérprete isso usa? Quando eu testo, ele é emitido em UTF-8, mesmo que a entrada esteja na página de códigos de Jelly (e a alteração na codificação tornaria isso impossível).

1
A codificação da saída depende das configurações do seu terminal: se estiver definido como UTF-x, ele será usado; se estiver definido para qualquer outra coisa, ele usa a página de código de Jelly. No Linux, LANG=en_USconsegue exatamente isso. tio.run/nexus/bash#@@/…
Dennis
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.