7 , 410 caracteres, 154 bytes na codificação 7, 0 letras = pontuação 154
55104010504200144434451510201304004220120504005434473340353241135014335450302052254241052253052244241052335452241114014241310052340435303052335442302052335500302052335430302052313340435303135014243241310335514052312241341351052302245341351525755102440304030434030421030442030424030455733413512410523142410523030523112411350143355142410523414252410523102410523002410523413342411145257551220304010420030455741403
Experimente online!
Em um desafio que não gosta de usar letras, qual idioma melhor usar do que um que consiste apenas em dígitos?
Este é um programa completo que sai por travamento; portanto, há saída estranha para o stderr, mas o stdout está correto.
Explicação
Um programa 7, em sua primeira iteração, simplesmente envia vários elementos para a pilha (porque dos 12 comandos existentes em 7, apenas 8 deles podem ser representados em um programa de origem e esses 8 são especializados para escrever código empurrar estruturas de dados específicas para a pilha). Este programa não usa o 6
comando (que é a maneira mais simples de criar estruturas aninhadas, mas de outra forma tende a não aparecer literalmente em um programa de origem); portanto, são apenas os 7
comandos que determinam a estrutura; 7
empurra um novo elemento vazio para o topo da pilha (enquanto os comandos 0
… 5
são apenas anexados ao topo da pilha). Assim, podemos adicionar espaços em branco ao programa para mostrar sua estrutura:
551040105042001444344515102013040042201205040054344 7
33403532411350143354503020522542410522530522442410523354522411140142413100523
40435303052335442302052335500302052335430302052313340435303135014243241310335
514052312241341351052302245341351525 7
55102440304030434030421030442030424030455 7
33413512410523142410523030523112411350143355142410523414252410523102410523002
41052341334241114525 7
551220304010420030455 7
41403
Os elementos próximos ao final do programa são pressionados por último, portanto, estão no topo da pilha no início da segunda iteração. Nesta iteração e em todas as iterações futuras, o interpretador 7 faz automaticamente uma cópia da parte superior da pilha e a interpreta como um programa. O literal 41403
empurra o (código ativo e não literal) 47463
(7 tem 12 comandos, mas apenas 8 deles têm nomes; portanto, uso negrito para mostrar o código e não negrito para mostrar o literal que gera esse código, o que significa esse, por exemplo, 4
é o comando anexado 4
ao elemento da pilha superior). Portanto, o programa que é executado na segunda iteração é 47463
. Aqui está o que isso faz:
47463
4 Troque os dois elementos da pilha do topo, adicione um elemento vazio entre
7 Adicione um elemento da pilha vazio ao topo da pilha
4 Troque os elementos da pilha do topo, adicione um elemento vazio entre
6 Descubra quais comandos gerariam o elemento da pilha do topo;
acrescente isso ao elemento abaixo (e pop o topo antigo da pilha)
3 Crie o elemento da pilha superior, pop o elemento abaixo
Isso é mais fácil de entender se observarmos o que acontece com a pilha:
- … D c b a
47463
(código a ser executado 47463
:)
- … D c b esvazie a (código a ser executado :)
47463
7463
- … D c b esvazia um vazio (código a ser executado :)
47463
463
- … D c b vazio vazio vazio a (código a ser executado :)
47463
63
- … D c b vazio vazio " a " (código a ser executado :)
47463
3
- … D c b vazio (código a ser executado: vazio )
47463
Em outras palavras, pegamos o topo da pilha a , calculamos o código que provavelmente o produziu e produzimos esse código. O intérprete 7 exibe automaticamente os elementos vazios da parte superior da pilha no final de uma iteração; portanto, terminamos com a 47463
parte de trás na parte superior da pilha, assim como no programa original. Deve ser fácil ver o que acontece a seguir: acabamos agitando todos os elementos da pilha, um após o outro, produzindo todos eles, até que a pilha fique sem fluxo e o programa trave. Então, basicamente criamos um loop de saída simples que analisa o código-fonte do programa para determinar o que produzir (não estamos produzindo as estruturas de dados que foram enviadas para a pilha pelos nossos 0
…5
comandos, em vez disso, estamos recriando quais comandos foram usados, observando quais estruturas foram criadas e produzindo essas). Portanto, a primeira parte da saída de dados é 551220304010420030455
(o código fonte que gera o segundo elemento da pilha do topo), a segunda é 3341351…114525
(o código fonte que gera o terceiro elemento da pilha do topo) e assim por diante.
Obviamente, porém, essas partes do código-fonte não estão sendo codificadas como saída. 7 contém várias linguagens específicas de domínio diferentes para codificar a saída; depois que um idioma específico do domínio é escolhido, ele permanece em uso até que seja explicitamente limpo, mas se nenhum dos idiomas tiver sido escolhido ainda, o primeiro dígito do código emitido determinará qual dos idiomas usar. Neste programa, apenas dois idiomas são usados: 551
e 3
.
551
é bastante simples: é basicamente o antigo código Baudot / teletipo usado para transmitir letras por teletipos, como um conjunto de caracteres de 5 bits, mas modificado para deixar todas as letras em minúsculas. Portanto, o primeiro pedaço de código a ser decodificado da seguinte maneira:
551 22 03 04 01 04 20 03 04 55
c a SP e SP n a SP reset output format
Como pode ser visto, estamos ajustando cada caractere em dois dígitos octais, o que é uma taxa de compressão bastante decente. Pares de dígitos no intervalo de 0 a 5 nos dão 36 possibilidades, em oposição às 32 possibilidades de que Baudot precisa; portanto, os quatro restantes são usados para comandos especiais; nesse caso, 55
no final limpa o formato de saída lembrado, permitindo usar um formato diferente para a próxima parte de produção que produzimos.
3
é conceitualmente ainda mais simples, mas com um toque. A idéia básica é pegar grupos de três dígitos (novamente, na faixa de 0 a 5, como esses são os dígitos para os quais podemos garantir que podemos recriar o código fonte original de sua saída), interpretá-los como um dígito de três dígitos número na base 6 e apenas o produza como um byte em binário (permitindo assim a saída dos caracteres multibyte na saída desejada simplesmente com a saída de vários bytes). A reviravolta, no entanto, vem do fato de haver apenas 216 números de três dígitos (com possíveis zeros à esquerda) na base 6, mas 256 bytes possíveis. 7 contorna isso ligando números de 332₆ = 128₁₀ para cima a dois bytes diferentes; 332
pode gerar o byte 128 ou 192, 333
o byte 129 ou 193 e assim por diante, até o 515
qual gera o byte 191 ou 255.
Como o programa sabe qual das duas possibilidades gerar? É possível usar trigêmeos de dígitos para 520
cima para controlar isso explicitamente, mas neste programa não precisamos: O padrão do 7 é escolher todos os bytes ambíguos de forma que a saída seja UTF-8 válida! Acontece que sempre há, no máximo, uma maneira de fazer isso, desde que seja UTF-8 que desejemos (e o fazemos neste caso), podemos apenas deixá-lo ambíguo e o programa funciona de qualquer maneira.
O final de cada uma das 3…
seções é 525
, que redefine o formato de saída, voltando à 551
próxima seção.
a
s - ou não, dependendo de quantos letras seriam necessárias, porque 20 caracteres é uma penalidade muito grande (embora quando tudo o mais seja marcado por bytes, não esteja muito bem definido ...)!