var QUESTION_ID=69;
var OVERRIDE_USER=98;
var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe";var COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk";var answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;function answersUrl(index){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+index+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}
function commentUrl(index,answers){return"https://api.stackexchange.com/2.2/answers/"+answers.join(';')+"/comments?page="+index+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}
function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(data){answers.push.apply(answers,data.items);answers_hash=[];answer_ids=[];data.items.forEach(function(a){a.comments=[];var id=+a.share_link.match(/\d+/);answer_ids.push(id);answers_hash[id]=a});if(!data.has_more)more_answers=!1;comment_page=1;getComments()}})}
function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(data){data.items.forEach(function(c){if(c.owner.user_id===OVERRIDE_USER)
answers_hash[c.post_id].comments.push(c)});if(data.has_more)getComments();else if(more_answers)getAnswers();else process()}})}
getAnswers();var SCORE_REG=(function(){var headerTag=String.raw `h\d`
var score=String.raw `\-?\d+\.?\d*`
var normalText=String.raw `[^\n<>]*`
var strikethrough=String.raw `<s>${normalText}</s>|<strike>${normalText}</strike>|<del>${normalText}</del>`
var noDigitText=String.raw `[^\n\d<>]*`
var htmlTag=String.raw `<[^\n<>]+>`
return new RegExp(String.raw `<${headerTag}>`+String.raw `\s*([^\n,]*[^\s,]),.*?`+String.raw `(${score})`+String.raw `(?=`+String.raw `${noDigitText}`+String.raw `(?:(?:${strikethrough}|${htmlTag})${noDigitText})*`+String.raw `</${headerTag}>`+String.raw `)`)})();var OVERRIDE_REG=/^Override\s*header:\s*/i;function getAuthorName(a){return a.owner.display_name}
function process(){var valid=[];answers.forEach(function(a){var body=a.body;a.comments.forEach(function(c){if(OVERRIDE_REG.test(c.body))
body='<h1>'+c.body.replace(OVERRIDE_REG,'')+'</h1>'});var match=body.match(SCORE_REG);if(match)
valid.push({user:getAuthorName(a),size:+match[2],language:match[1],link:a.share_link,})});valid.sort(function(a,b){var aB=a.size,bB=b.size;return aB-bB});var languages={};var place=1;var lastSize=null;var lastPlace=1;valid.forEach(function(a){if(a.size!=lastSize)
lastPlace=place;lastSize=a.size;++place;var answer=jQuery("#answer-template").html();answer=answer.replace("{{PLACE}}",lastPlace+".").replace("{{NAME}}",a.user).replace("{{LANGUAGE}}",a.language).replace("{{SIZE}}",a.size).replace("{{LINK}}",a.link);answer=jQuery(answer);jQuery("#answers").append(answer);var lang=a.language;lang=jQuery('<i>'+a.language+'</i>').text().toLowerCase();languages[lang]=languages[lang]||{lang:a.language,user:a.user,size:a.size,link:a.link,uniq:lang}});var langs=[];for(var lang in languages)
if(languages.hasOwnProperty(lang))
langs.push(languages[lang]);langs.sort(function(a,b){if(a.uniq>b.uniq)return 1;if(a.uniq<b.uniq)return-1;return 0});for(var i=0;i<langs.length;++i)
{var language=jQuery("#language-template").html();var lang=langs[i];language=language.replace("{{LANGUAGE}}",lang.lang).replace("{{NAME}}",lang.user).replace("{{SIZE}}",lang.size).replace("{{LINK}}",lang.link);language=jQuery(language);jQuery("#languages").append(language)}}
body{text-align:left!important}#answer-list{padding:10px;float:left}#language-list{padding:10px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="https://cdn.sstatic.net/Sites/codegolf/primary.css?v=f52df912b654"> <div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td><a href="{{LINK}}">{{SIZE}}</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td><a href="{{LINK}}">{{SIZE}}</a></td></tr></tbody> </table>
Respostas:
Hexagonia , comprimento lateral
1716,816705 bytesExperimente online!
Isto é o que parece desdobrado:
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:
fonte
!
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?MySQL, 167 caracteres
Está certo. :-)
Eu realmente escrevi esse aqui. Foi originalmente publicado no meu site .
fonte
GolfScript, 2 bytes
(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
: pressione 9 para a pilha,
: consome o 9 como argumento, empurre o array[0 1 2 3 4 5 6 7 8]
para a pilha(
: consome a matriz como argumento, empurre a matriz[1 2 3 4 5 6 7 8]
e o item0
para a pilha;
: descartar o item superior da pilhaA 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.fonte
1
não é um problema no GolfScript: ele gera1\n
, onde\n
denota uma nova linha. No entanto, o programa de dois caracteres1\n
é uma opção.\n
provavelmente também é?Brain-Flak ,
9.8e5801.3e5629.3e51612818110244452433242404200418038523656361635402485 + 3 = 2488 bytesAgora 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.
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
fonte
Prelúdio ,
51574514234817611537664569535423241214184178175169148142136136 bytesAgradecimentos ao Sp3000 por salvar 3 bytes.
Isso é bastante longo ...(tudo bem, ainda é longo ... pelo menos está superando oquesito BrainfuckC # 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. :)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 a4
e depois a2
. Não há como empurrar números maiores diretamente, você precisará adicioná-los. Os valores podem ser copiados das pilhas adjacentes comv
e^
. 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
^
ev
é sinônimo. Isso é bom porquev
tem 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 caracteres2
, 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,0
tem um 0 em sua representação (50), mas realmente não precisamos0
. 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:
Divida em pares e inverta, subtraia dois e procure os códigos de caracteres:
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:
Primeiro, pressionamos
7
a primeira voz - se não fizermos isso, nunca entraremos no loop (para o esqueleto é importante que isso seja diferente de zero ... por que especificamente7
veremos 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 que7
colocamos na primeira pilha ainda está lá, então o loop se repete.Desta vez, também há um
7
na 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 agora7
a 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=
: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 transforma7
a 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:
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
2
não faz parte do loop, então o corpo do loop é na verdade o+8+2
que adiciona 10 (usando o2
pressionado 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
-7
na parte inferior). O resto é bastante simples: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
8
vezes e adiciona6
cada vez. O resultado é impresso com!
e8
no final é para a próxima iteração.Então, o que acontece com o
-7
? Sim,48 - 7 = 41
qual é o código de caractere de)
. Magia!Finalmente, quando terminamos esse loop, descartamos o
8
que pressionamos#
para garantir que deixemos o loop externo na segunda voz. Nós pressionamos todos os dígitos novamente e o programa termina.fonte
Hexagonia , comprimento lateral 11, 314 bytes
Experimente online!
Versão antiga:
Hexagonia , comprimento lateral 11, 330 bytes
Experimente online!
Codificador: Experimente online!
O programa é aproximadamente equivalente a este código Python: Experimente online!
Código desdobrado:
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.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.!
imprimee
$
pula para o próximo>
.A partir do
<
. Se o valor da memóriamem
for falso (<= 0
ou seja, a condiçãomem > 0
não for atendida), concluímos a impressão do programa e devemos sair. O IP seguiria o caminho superior.(deixe o IP ser executado em
todo o mundopor 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.
Agora a memória fica assim:
Se o valor for verdadeiro:
o seguinte código é executado:
Veja a explicação detalhada do
Q4
em 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,
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
Supondo que deixemos
a
ser o valor da célula atual eb
o valor da célula certa, uma tradução direta disso para BF é:No entanto, observe que não precisamos estar na mesma posição o tempo todo durante o programa. Podemos deixar que o valor
a
seja o que somos no início de cada iteração, então temos este código: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:
\
que reflete isso, agora segue direto)
Se o valor (da operação mod 2 acima) for falso (zero), seguiremos este caminho:
Não vou explicar muito detalhadamente aqui, mas o deslocamento na verdade não é exatamente
33
, mas é congruente ao33
mod256
. Echr
tem um implícito% 256
.fonte
Vim, 11 bytes
iq"qP<Esc>
: Insira manualmente uma duplicata do texto que deve estar fora da gravação.q"
ehqP
: Grave o interior diretamente no""
registro sem nome , para que possa ser colado no meio. Oh
é 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,"0
para arranjos ou"1
para 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á,"0
mas""
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.
fonte
y
ou algo antes de executar pode ajudar␛
exibir pressionando a tecla <Esc>? Parte deste bloco Unicode “Control Pictures”<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.Cubix , 20 bytes
Quase consegui o
\o/
...Líquido :
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:
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
,S
eQ
, que empurram10
,32
e34
, 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 useiS
(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 oQ
(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.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):
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
Q
no 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.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:
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).
Este é um loop, como você pode ter visto / esperado. O corpo principal é:
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.fonte
Javascript ES6 - 21 bytes
Eu chamo isso de quine "O Bling Quine".
Às vezes, você precisa jogar golfe com estilo.
fonte
!$=_=>`!$=${$}()`()
economiza 2 bytes?Invalid assignment left hand side
. Gostaria que funcionasse :(Array.prototype.join
.alert
ouconsole.log
após a função de seta e colocar a cadeia de modelo entre parênteses funcionaria.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!
fonte
ESultanik's Quine!
configura a memória como uma pilha de codificaçãoESultanik'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.Hexagonia , comprimento lateral
15 14 1312,616 533 456383 bytesApós vários dias de golfe cuidadoso, reorganizando os loops e recomeçando, finalmente consegui reduzi-lo para um hexágono lateral 12.
Experimente online!
Desdobrado:
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:O número é codificado na primeira metade do hexágono, com todas as
no lado esquerdo e o
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
->
:!
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
.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: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
Isso executa,
='=:'
que divide o número atual por 80 e navega para a célula correta.Versão antiga (comprimento lateral 13)
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.
fonte
PostScript, 20 caracteres
Curto e legítimo. 20 caracteres, incluindo nova linha à direita.
fonte
Cubix , 45 bytes
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:
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;
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.O
u
comando 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.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 oW
comando 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 umR
, para virar à direita e seguir para a esquerda ao longo da linha superior; depois,$
pula aR
via 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.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 oo
comando, efetivamente deixando a quinta coluna totalmente vazia. Então, voltamos aou
comando, 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 oo
comando anteriormente.) Encontramos um par deR
comandos e os usamos para fazer uma inversão de marcha "manual" (o segundoR
comando aqui foi usado anteriormente para alcançar o primeiro linha, então parecia mais natural ajustar outroR
comando ao lado dela.W
comando, 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 umo
(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) .
fonte
"
éQ
.Python 2, 30 bytes
Retirado daqui
fonte
_
, mas fica melhor se você o atribuir a qualquer letra, ou seja, s:s='s=%r;print s%%s';print s%s
Teclas Vim,
17, 14Algué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 :
Esta é a primeira pergunta que eu já fiz, e
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á:
Experimente online!
Observe que quando você digitar isso, ele exibirá o
<esc>
pressionamento de tecla como^[
. Isso ainda é preciso, pois^[
representa0x1B
, 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 dicas explicando isso aqui , se você quiser mais informações, mas basicamente você precisa iniciar o vim com
ou digite
qqq
antes de executar isso.Explicação:
Em uma nota lateral, esta resposta é provavelmente um recorde mundial para a maioria dos q's em uma resposta PPCG, ou algo assim.
fonte
2i2i<esc>
está tão perto. Eu sinto que deve haver algo que eu possa fazer para fazer isso funcionar.<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.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á.Perdido ,
120 116 98 96 76 7066 bytesEdit: yay, abaixo de 100
Editar: salvou um monte de bytes alternando para todos os
/
s na linha inferiorExperimente 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 oO 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?1
objetivo é 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.fonte
Estes são os dois menores códigos de Ruby da SO :
e
Não me pergunte como o segundo funciona ...
fonte
<<2
inicia uma sequência na próxima linha e*2
repete a sequênciaFissão , 6 bytes
Parece que agora é o quine mais curto e "adequado" entre essas respostas.
Explicação
O fluxo de controle começa
R
com um único(1,0)
átomo à direita . Ele atinge o"
modo de impressão alternado e, em seguida, envolve a linha, imprimindo'!+OR
antes 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"
eO
imprime 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 comO
.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
J
umpNovamente, o código começa em
R
. Os@
swaps de massa e energia para dar(0,1)
. Portanto, oJ
átomo pula sobre aO
reta 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'"O
impressã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
Isso tem dois átomos, começando a partir da esquerda e indo da
L
direitaR
. O átomo à esquerda obtém seu valor definido pelo'"
qual é imediatamente impresso comO
(e o átomo é destruído). Para o átomo certo, trocamos massa e energia novamente, saltamos sobre oO
para imprimir o restante do código no modo de impressão. Posteriormente, seu valor é definido por,'L
mas isso não importa, pois o átomo é descartado;
.fonte
'!+
codifica"
.|R@JO"'
funcionaria, ou você ainda precisaria desse espaço após o'
?'
primeiro.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:
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):Ou convertido em um bookmarklet (custando 22 caracteres):
fonte
C,
6460 bytesAté 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:
main(s)
main
argumentos de abuso , declarando uma variável praticamente sem tipos
. (Observe que,s
na verdade, não é digitado, mas, como os compiladores listados o convertem automaticamente conforme necessário, pode ser *.)printf(s="..."
defines
a string fornecida e passa o primeiro argumento paraprintf
.s
está definido paramain(s){printf(s=%c%s%1$c,34,s);}
.%c
está definida para ASCII34
,"
. Isso torna a solução possível. Agoras
se parece com isso:main(s){printf(s="%s%1$c,34,s);}
.%s
é definido paras
si mesmo, o que é possível devido ao item 2. Agoras
se parece com isso:main(s){printf(s="main(s){printf(s=%c%s%1$c,34,s);}%1$c,34,s);}
.%1$c
está definida para ASCII 34"
,printf
da primeira ** argumento. Agora,s
fica 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
printf
o especificador de formato estivesse acessível via$
, isso funcionaria para 52 bytes:fonte
s
é do tipoint
, não uma "variável não digitada".s=3
obviamente não funcionaria porque você precisa passar a string duas vezes paraprintf
.Java, 528 bytes:
Uma solução Java com uma abordagem original:
na forma legível:
fonte
if(++i==92)
,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);}}
ondeabc
seria o número mágico recém-calculado String. Em java 8+ também é possível mudarclass a{public static void main
parainterface a{static void main
, e em Java 10 + também é possível mudarimport java.math.*;
eBigInteger b=new BigInteger(
paravar b=new java.math.BigInteger(
.Frango , 7
Não, isso não é ecoado diretamente :)
fonte
chicken
!Retina ,
201497 bytesAntes 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 os0
s 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.fonte
Javascript (36 caracteres)
Este é, AFAICT, o quine javascript mais curto publicado até o momento.
fonte
a
, poderá acessar seu conteúdo chamandoa.toString
.a
exatamente 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.!function a(){alert("!"+a+"()")}()
.(a=()=>alert(
($ {a})))()
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:
Experimente online!
Portanto, o problema é que o GolfScript não imprime um avanço de linha à direita, mas imprime o conteúdo
n
no final do programa. É apenas quen
conté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 emn
impressõ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:
Novamente, precisamos do avanço de linha à direita.
fonte
Labirinto ,
12411053 bytesGraças ao Sp3000 por jogar 9 bytes, o que me permitiu jogar outros 7.
Experimente online!
Explicação
Labirinto 101:
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:
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 imprimemod
e continua trabalhando com odiv
até 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: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), obtemosAgora 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:
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:Desde que a parte superior da pilha ainda não seja zero, o IP executará esse código bastante denso no seguinte loop:
Ou dispostos linearmente:
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):
Quando
N
chegar 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), executa6
novamente. Isso torna o topo da pilha positivo, de modo que o IP vire à direita (sul) e execute o9
. O topo da pilha é agora69
, 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:
O problema é que agora alteramos o
"
para a3
, o que também altera o número real que queremos ter. E com certeza esse número não termina3
. 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
3
nesse 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:@
para/
. Nesse caso, podemos usar qualquer dígito1357
e 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._
). 26 escolhas oferecem muitas possibilidades. Por exemplo, paraA
qualquer 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.1
, a codificação também termina1
. 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.fonte
Perdido ,
293262249 bytesExperimente 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.
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.
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 roubeiemprestado o Klien Quine para Martin Ender .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.
fonte
YUP ,
1165879606561540522498 + 7 = 505 bytesRequer o
-cheat
sinalizador para permitir a definição de aliases.Experimente online!
Explicação
Existem duas partes para isso (como na maioria dos quines). Os dados:
E o decodificador:
Os dados são apenas uma codificação binária do decodificador (ou melhor, seu reverso). Cada
0
começa um novo personagem e os1
s e2
s são0
- e1
-bits, respectivamente.Observe que
0
é um comando Yup padrão que empurra um zero, enquanto1
e2
não está definido neste momento. No entanto, atribuímos toda a parte dos dados ao comando%
para que o1
e2
possa permanecer indefinido até que%
seja realmente usado.Em seguida, definimos mais alguns comandos:
<
diminui o topo da pilha,>
aumenta-o.1
(de maneira não intuitiva) dobra a parte superior da pilha.2
dobra e depois incrementa. Graças a essas definições, algo como0221111
, 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.
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.
fonte
Fueue , 423 bytes
Fueue é um esolang baseado em fila no qual o programa em execução é a fila.
Experimente online!
Como funciona
Esta explicação
pode ou não tersaí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:
+*/-%
: 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:
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]
atrasosA
para um ciclo. (Provavelmente, o método mais fácil e mais legível.)~ef
troca os elementose
ef
também atrasa sua execução. (Provavelmente o menos legível, mas geralmente o mais curto para pequenos atrasos.)$1e
atrasa um único elementoe
.-
e%
são úteis para atrasar números (este último para0
e1
.):
ou$
pode ser usado para criá-los a partir de um único.(n
envoltóriosn
entre 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:
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,
10
codifica 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.
0
como número inteiro48
), dividindo primeiro os dígitos menos significativos. Produz um dígito a cada 15 ciclos.[x[y]]
, imprimindo também o caractere codificado de cada par.[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.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.$
função cria 4255 cópias do seguinte,%
enquanto a(
coloca~
entre colchetes.%
é usado para alternar o seguinte número entre0
e1
.%
s são usados, ele$1
cria 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.
:
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.:<
se transforma<<
e~
troca dois dos blocos, colocando o código para uma nova seção C por último.<
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.)
colchetes externos são removidos. Em seguida,~:)
vira):
e~)
troca a)
para o início do código da seção C.)
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: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
x
ey
representando 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.~
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 quecausa danosmanipula 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.~
linha tem um~~
restante, que troca um ao~
longo do seguinte)
. O outro<
anexa a seção D a um[)))~]
bloco.~
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.
(
envolve a função de paradaH
entre colchetes. A-
seguir, ele será usado como um elemento fictício para a primeira iteração, em vez de um par de dígitos.[49[49]]
correspondente à final11
do numeral.[49[48]]
(correspondente ao10
iní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 emA[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 aH
interrupçã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
x
ey
representando os códigos ASCII dos dígitos.10*x+y-498
o valor ASCII do caractere codificado.498 = 10*48+48-30
,48
desfaz a codificação ASCII dex
ey
enquanto30
muda a codificação de00–99
para para30–129
, o que inclui todos os ASCII imprimíveis.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
0
dígitos redundantes serão coletados aqui.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
0
dígitos quando o número for reduzido a 0, até que a seção D interrompa o programa inteiro com aH
funçã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:
A iteração típica
N
indica o número a ser dividido:+:5
vez de--10
atrasar10
dois ciclos. Infelizmente, apenas um dos10
s no programa foi ajudado por isso.[N]
e[BkG]
são duplicados e, em seguida, uma cópiaN
é dividida por10
.[{N/10}]
é duplicado, mais funções aritméticas são usadas para calcular o código ASCII do último dígito deN
as48+((-10)*(N/10)+N)
. O bloco com este código ASCII é deixado para a seção F.[{N/10}]
é trocada entre os[BkG]
blocos para configurar o início de uma nova iteração.Quine de bônus (540 bytes)
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.
fonte
)$n[)](
é um byte mais curto para o contador de atraso.Geléia, 3 bytes
Experimente online!
Verificação
Como funciona
fonte
LANG=en_US
consegue exatamente isso. tio.run/nexus/bash#@@/…