Golfe um intérprete roxo
Roxa é um esolang que é projetado com dois objetivos principais:
- Para ser uma minimização de Aubergine , já que simplesmente não existem linguagens de instrução única modificáveis o suficiente.
- Admitir a possibilidade de terrivelmente pequena intérpretes de golfe. Minha primeira passagem em um intérprete razoavelmente completo de Python 2 tem apenas 702 bytes, e tenho certeza de que um jogador mais experiente pode se barbear um pouco com isso.
Seu objetivo é escrever um intérprete para esse idioma.
Informação sobre Estados Unidos da América:
Um programa Purple é uma sequência de caracteres inseridos em uma matriz de memória infinita e endereçável, de modo que o primeiro caractere do programa seja colocado no endereço zero. O restante da matriz (antes e depois de onde o programa Purple está armazenado) é inicializado como zero.
Há três registros em roxo, chamados a e b e i , cada um dos quais pode conter um inteiro assinado e é inicializado para zero. i também é o ponteiro da instrução e sempre aponta para a instrução Purple em execução no momento.
A cada ciclo, o intérprete lê uma sequência de três caracteres contíguos, começando na localização da memória indicada pelo ponteiro da instrução e tenta executar essa sequência como a instrução Roxa. Depois, o ponteiro da instrução é sempre incrementado em 3.
Sintaticamente, a instrução Purple consiste em três caracteres (ou codificações) em uma linha, como " xyz ".
O primeiro caractere x pode ser um dos seguintes:
abABio
Esses símbolos têm o seguinte significado:
a - Place the result in register a.
b - Place the result in register b.
A - Place the result in the location in memory referred to by register a.
B - Place the result in the location in memory referred to by register b.
i - Set the instruction pointer to the result.
o - Output the result to stdout.
Os outros dois bytes y e z podem ser qualquer um dos seguintes:
abABio1
Cada um desses símbolos tem o seguinte significado:
a - Return the contents of register a.
b - Return the contents of register b.
A - Return the contents of the memory array at the address stored in register a.
B - Return the contents of the memory array at the address stored in register b.
i - Return the contents of register i (the instruction pointer).
o - Return the value of a single character read from stdin.
1 - Return the literal numeric value 1.
Após buscar a instrução, o intérprete Purple avaliará ye depois z , subtrairá o resultado de z do resultado de y e executará a ação indicada por x na diferença.
Se a sequência de três caracteres (ou suas codificações) não for uma instrução roxa válida, o intérprete será interrompido imediatamente sem erros.
Seu intérprete deve:
- Seja um programa completo, não uma função.
- Nunca envie para stderr, a menos que EOF seja lido .
- Comporte-se de maneira idêntica à implementação de referência em todas as entradas bem formadas que não envolvam números muito grandes, incluindo os programas de teste fornecidos abaixo. (Bem, identicamente até o momento - ele pode ser mais lento, mas não muito!)
Você pode fornecer o programa ao intérprete da forma que desejar: leia-o de um arquivo, incorpore-o ao programa como uma string ou leia-o de stdin.
Casos de teste:
O programa
ooo
quando executado com entrada
z!
deve render
Y
O programa
bbboobiii
quando executado com entrada
It's a cat program.
(ou qualquer outra entrada) deve render
It's a cat program.
(ou qualquer outra entrada recebida) e, em seguida, comece novamente e faça a mesma coisa novamente .
O programa
Aoab11bi1bABoAaiba
quando executado com entrada
0
deve render
0
e depois parar, mas quando executado com entrada
1
deve continuar produzindo
1
para sempre.
O programa
b1bbb1oAbabaa1ab1Ab1Bi1b
deve render
b1bbb1oAbabaa1ab1Ab1Bi1b
O programa
aA1aa1bb1oAbbi1bb1bbAb1Bi1b Purple is the awesomest! Why haven't you tried it yet?
!dlroW ,olleG
deve render
Hello, World!
Pontuação:
Esse é o código-golfe , e a fonte mais curta em bytes, potencialmente modificada pelo bônus a seguir, vence.
Bônus:
- -10% se o seu intérprete lê um nome de arquivo do stdin ou de um argumento da linha de comando e carrega o programa a partir do arquivo.
fonte
uint32
caracteres e MAXINT para intsRespostas:
Pyth,
148128121 bytes (ou 124 * .9 = 111.6, veja abaixo)Suíte de teste
Código fornecido na primeira linha do STDIN, entrada para o programa Purple no restante do STDIN. Para usar código com novas linhas, use a versão alternativa na parte inferior.
Razoavelmente golfe. Aqui está isso com quebras de linha e recuo para maior clareza:
Basicamente, um
#
loop executa e interrompe via quebra de erro.a
eb
são combinados em uma única variávelJ
,.Z
é o ponteiro da instrução.k
é inserido no programa Purple.H
é a fita, representada como um dicionário.b
é o resultado atual.Y
é o primeiro byte atual da instrução.Lendo do arquivo:
Dê o nome do arquivo como primeira linha de STDIN. Execução de teste:
fonte
JavaScript (ES6), 292 bytes
Explicação
As respostas JavaScript são sempre estranhas quando
STDIN
eSTDOUT
são necessárias ...O primeiro prompt é a entrada para a sequência de programas. Cada prompt que resulta de um
o
instrução lerá apenas o primeiro caractere.eval
é usado para substituir uma frase comum que salva alguns bytes. Ungolfed e sem oeval
programa é assim:fonte
c="charCodeAt"
ser substituído por apenasc
?array[-1] = 1
é o mesmo quearray = { "-1": 1 }
. Ambos podem ser acessados comarray[-1]
.Ceilão,
827792671 bytesEle se comporta de maneira um pouco diferente da implementação de referência quando o programa tenta ler a entrada no EOF - a implementação de referência trava com um TypeError, que é muito caro para reproduzir aqui (e provavelmente um bug), portanto, retornará -1 ( repetidamente, se necessário).
(Ao tentar gravar este -1 no stdout, o intérprete terminará com um OverflowError. Semelhante acontecerá se um número inteiro fora do intervalo Unicode for gerado.)
O intérprete toma o programa como seu primeiro argumento de linha de comando (lembre-se de citá-lo para seu shell quando ele contiver espaço em branco ou outras coisas interessantes).
No Ceilão, podemos ler facilmente as entradas de maneira fácil (acho que isso mudará em uma das próximas versões); portanto, quando
o
é usado para leitura, estou lendo uma linha inteira e armazenando as peças em buffer para usos futuros. Eu acho que funciona de maneira semelhante na implementação do Python quando conectado a um terminal.Ao tentar executar um comando (parte) que não é um dos caracteres válidos, isso
nothing
fará com que um AssertionError seja lançado, que então capturamos no bloco catch ao redor do loop principal.Eu acho que esse preferencialmente deve ser um tipo de exceção personalizado (como AssertionError também pode ocorrer em outros lugares, se eu tiver um bug), mas isso exigiria muito mais espaço, consumindo a maioria das melhorias que fiz da primeira versão.
Alguns truques usados para jogar golfe:
map
função e criamos um novo a cada vezA
ouB
é usado como x .variable
anotação, que é agoral
).E
(para o meio ambiente) e dos
método (step) - tudo agora acontece dentro darun
função..integer
para obter o ponto de código de um caractere,.hash
obtém o mesmo resultado. Assimstring*.hash
é o mesmo questring.map(Character.integer)
(fornece uma iterável dos pontos de código de uma string).is I ...
é menor queexists ...
.x
) em uma string,"``t``"
é mais curto quet.string
(ou, o que eu usei para um caractereString{t}
).Aqui está a versão formatada (e comentada):
fonte