Este é o Desafio Semanal # 2. Tema: Tradução
Escreva um programa ou função que receba o código fonte de um programa no Prelude e envie o código para um programa equivalente no Befunge-93 . Para que o programa seja equivalente, ele deve, para qualquer entrada fornecida, produzir a mesma saída que o programa Prelude e interromper se e somente se o programa Prelude parar.
Idioma de entrada: Prelude
Intérprete Python:
Um programa Prelude consiste em várias "vozes" que executam instruções simultaneamente. As instruções para cada voz estão em uma linha separada. Cada voz tem uma pilha separada, que é inicializada com uma quantidade infinita de zeros. A execução começa na coluna mais à esquerda e avança uma coluna para a direita a cada tick, exceto quando influenciada por )
ou (
instruções. O programa termina quando a última coluna é atingida.
Prelude especificações para este desafio:
Digits 0-9 Push onto the stack a number from 0 to 9. Only single-digit
numeric literals can be used.
^ Push onto the stack the top value of the stack of the above
voice.
v Push onto the stack the top value of the stack of the below
voice.
# Remove the top value from the stack.
+ Pop the top two integers from the stack and push their sum.
- Pop the top two integers from the stack, subtract the topmost
from the second, and push the result.
( If the top of the stack is 0, jump to the column after the
matching `)` after the current column executes.
) If the top of the stack is not 0, jump to the column after
the matching `(` after the current column executes.
? Read an integer from STDIN.
! Pop one value from the stack and print it to STDOUT as an
integer.
<space> No-op
Notas
v
e^
aja de forma cíclica, para que av
voz na parte inferior copie o elemento de pilha da voz superior e^
na voz superior copie da voz inferior. Corolário: Ambosv
e^
duplicar o topo da pilha em um programa de voz única.- A
(
e sua correspondência)
podem estar localizadas em linhas diferentes. No entanto , a)
sempre observará a pilha da voz em que o correspondente(
foi colocado, e não a pilha em que o)
próprio é colocado. - Os valores produzidos pelas instruções
^
ev
operam com os valores presentes antes da conclusão de quaisquer outras operações na mesma coluna. ?
e!
opere de maneira diferente da especificação encontrada em esolangs.org, portanto, teste com o intérprete levemente modificado fornecido nesta publicação.
A entrada é garantida para ter:
- Parênteses correspondentes
- Não há mais de um parêntese em uma coluna
- Mesmo número de caracteres em cada linha
- Pelo menos uma linha
- Nenhuma coluna com mais de uma instrução de E / S (
!
ou?
) - Um caractere de avanço de linha após as instruções para cada voz
- Nenhum caractere além dos mencionados acima
Idioma de saída: Befunge-93
Befunge é uma linguagem baseada em pilha cujo contador de programa (PC; um ponteiro para a instrução atual) se move livremente em uma grade bidimensional. Começa no canto superior esquerdo, movendo-se para a direita. O campo de jogo é toroidal, ou seja, o movimento do PC envolve as duas extremidades. O Befunge também possui uma pilha que é inicializada com um número infinito de zeros. Befunge tem as seguintes operações:
Você pode assumir as seguintes características do compilador / intérprete Befunge-93:
- Os números inteiros são de precisão ilimitada.
- Permite grades de qualquer tamanho.
- As coordenadas da grade (para
g
ep
) são baseadas em 0.
Pontuação
Para impedir envios que simplesmente produzam um intérprete do Prelude no Befunge e codifiquem a fonte do Prelude nele, o objetivo será minimizar o tamanho do código-fonte do Befunge resultante.
Abaixo são fornecidos vários programas do Prelude. Seu tradutor será executado em tudo isso. Sua pontuação é a soma dos tamanhos dos programas Befunge, desde que todos eles sejam válidos.
O seu tradutor não deve ser otimizado especificamente para esses casos de teste (por exemplo, codificando programas Befunge manuscritos para eles). Se eu suspeitar de alguma resposta, reservo-me o direito de alterar entradas ou criar outras.
Entradas de amostra
Imprima n-1
para 0
:
?(1-^!)
AND lógico:
? (0)
?(0 )
1 !
OU lógico:
? (0)
? (0)
1 1 !
Verifique a paridade da entrada (ou seja, módulo 2) do número não negativo:
?(1-)
^ v
v1-^^-!
Esquadrar a entrada:
^
^+ !
?(1-)
Imprimir o n th número de Fibonacci, onde n = 0
corresponde a 0 e n = 1
corresponde a 1:
0 v+v!
1 ^
?(1-)
Signum:
1) v # - !
vv (##^v^+)
?(# ^ ##
Divisão para entradas não negativas:
1 (# 1) v # - 1+)
vv (##^v^+)
? v-(0 # ^ #
?
1+ 1-!
Obviamente, seu programa deve exibir o mesmo comportamento para todos os casos, mesmo que o comportamento do programa de amostra para números negativos não seja especificado.
Por fim, seu tradutor não deve ser excessivamente longo:
- Ele deve estar contido em uma postagem do Stack Exchange
- Ele deve processar as entradas de amostra em menos de 10 minutos em um computador desktop típico.
Observe que uma entrada numérica para Prelude ou Befunge é fornecida como um sinal de menos opcional seguido por um ou mais dígitos decimais, seguido por uma nova linha. Outra entrada é um comportamento indefinido.
Você pode escrever seu tradutor em qualquer idioma. O menor código Befunge traduzido vence.
Entre os melhores
- Sp3000 : 16430 bytes
1
está dentro de um loop, portanto não pode ser pressionado. Um 0 pode vir da quantidade infinita de 0s que começa nas pilhas.Respostas:
Python 3, marcará mais tarde
Corra como
py -3 prefunge.py <input filename> <output filename>
.Tem sido uma semana lenta para mim, então eu finalmente estava entediada o suficiente para enfrentar essa questão de seis meses. Eu perguntaria por que ninguém mais tentou, mas ainda sinto a dor da depuração (e provavelmente ainda existem bugs ainda por saber).
A questão não fornece um intérprete Befunge-93, então usei este , que é um pouco diferente das especificações. As duas principais diferenças são:
Se um caractere não existir em uma determinada linha do programa, você não poderá gravar nessa linha. Isso significa que você precisará pressionar Enter várias vezes para introduzir novas linhas suficientes no final . Se você
NaN
vir s na saída, essa é a causa mais provável.As células da grade não são pré-inicializadas a zero - por conveniência, incluí alguma pré-inicialização nas saídas do Befunge, mas, como não é necessário, posso retirá-la quando começar a marcar.
O layout principal dos programas de saída é este:
O espaço da pilha está fora do programa, portanto, o comentário da nova linha Enter-spamming anterior.
A idéia central é atribuir a cada voz uma linha que serve como sua pilha. Para manter essas pilhas, também temos uma linha especial de comprimento da pilha, na qual o comprimento de cada pilha é registrado em uma célula ao longo da linha. O programa
g
contém muitas ets ep
uts, por exemplo, para imprimir o processo é:y = stack_row[stack], x = stack_length[stack]
.91+,
, ou seja, imprima como número inteiro e imprima uma nova linhastack_length[stack]
Para executar a avaliação simultânea de uma coluna, todas as células necessárias são lidas e seus valores são mantidos na pilha antes de qualquer célula ser gravada (por exemplo, no exemplo de impressão, pode haver mais instruções entre a primeira e a segunda etapas).
`
, que é maior que, é empregado para garantir que os comprimentos da pilha nunca sejam negativos e para pressionar 0s quando a pilha estiver vazia. É daí que surge a ramificação claramente visível, mas eu tenho uma idéia que removerá a ramificação, o que deve remover muito espaço em branco da primeira e terceira linhas.Para os loops, como os loops Prelude podem saltar para os dois lados, usamos duas linhas por loop em uma configuração como esta:
Atualmente, esses loops compõem a maioria dos bytes, mas podem ser facilmente reduzidos colocando-os na caixa de códigos
p
, o que pretendo fazer depois que estiver feliz que o tradutor esteja funcionando corretamente.Aqui está um exemplo de saída para
?(1-^!)
, ou seja, impriman-1
para0
:Quadrado da entrada:
Divisão (pequenas entradas são recomendadas):
Há também várias outras otimizações menores que vêm à mente, como substituir
07p07g
por:07p
, mas estou dando esse passo de cada vez :)fonte
Will score later
2 anos e contando! :)