Aqui está uma definição de linguagem muito simples:
A Variable is any string that does not contain ^, <, >, !, or ?
The empty string is a valid variable identifier
The value of every variable starts at 0.
A Statement is one of (var is a Variable, P is a Program):
var^ -> changes var to be equal to 1 more than itself
var<P> -> while var > 0, changes var to be equal to 1 less than itself, then runs P
var! -> output value of var
var? -> ask for non-negative integer as input, increase var by that value
A Program is a concatenation of Statements, running a Program means running each Statement in order
Programas de exemplo (observe que a cadeia vazia é uma variável, mas eu a usarei com moderação por questões de clareza, e algumas variáveis são zeradas no programa quando geralmente são 0 por padrão):
<>: sets the value of the empty string variable to 0
b<>b?b<a^>: asks for b, then adds the value stored in b to a, zeroing b in the process
b<>b?a<>b<a^>: asks for b, then sets a to the value of b, zeroing b in the process
a<>c<>b<a^c^>c<b^> : copies the value in b into a without zeroing it
b<>c<>a<c^c^c<b^>>b! : outputs a multiplied by 2
b^b<a<>a?a!b^> : outputs what you input, forever
Seu objetivo é escrever o menor intérprete para esse idioma.
O valor de uma variável pode ser arbitrariamente grande e deve ser limitado apenas pela memória total à qual seu idioma tem acesso, em teoria, mas você só precisa lidar com valores de até 2 ^ 256.
Seu programa deve ser capaz de lidar com programas arbitrariamente longos, em teoria, mas você só precisará trabalhar em programas com menos de 2 ^ 32 caracteres. Você também deve lidar com loops de profundidade aninhados até 2 ^ 32.
Você pode assumir que o programa é um programa válido e que você só receberá números inteiros não negativos quando solicitar entrada. Você também pode assumir que apenas caracteres imprimíveis ASCII estão incluídos na sequência de entrada.
A velocidade do programa que você interpreta não importa, já será dolorosamente lento para coisas tão simples quanto a multiplicação de 5 dígitos, sem otimização.
Se você deseja usar um idioma que não possa razoavelmente aceitar entrada ou produzir saída da maneira descrita pelo idioma, use qualquer interpretação que desejar. Isso se aplica a qualquer razão que seu idioma não possa implementar algum comportamento necessário. Eu quero que todos os idiomas possam competir.
O programa mais curto vence. Aplicam-se brechas padrão.
fonte
Respostas:
Ruby, 182 bytes
Tente assim:
Como funciona
A
r
função tokeniza uma sequência de entrada e executa cada token:Procuramos alguma
$2
correspondência de nome de variável[^!?^<>]*
, seguida por<...>
onde...
corresponde a zero ou mais programas (\g
é recursão); nesse caso,$4
não énil
!
,?
ou^
caráter, capturado por$3
, caso em que$4
énil
.Então a lógica para executar um token é bastante simples ao recuá-lo um pouco:
fonte
JavaScript (ES6) 184
194 209Editar simplificado (usar parâmetros de função para entrada e saída parecia uma boa idéia, mas não era), mais 1 byte salvo thx @ ӍѲꝆΛҐӍΛПҒЦꝆ
Editar 2 Análise modificada. A lógica para incremento / entrada é emprestada da resposta de @ Lynn
Menos golfe
TESTE O snippet começa a avaliar 2016 usando o programa publicado por @Neil. Seja paciente...
fonte
eval
para evitarreturn
não uma opção?Perl, 251 bytes
Versão mais fácil de ler:
Isso desperdiça um monte de bytes consertando loops para serem saltos diretos, mas a digitalização para trás em busca do loop ofendeu meu senso de estética.
fonte
C ++ padrão, 400 bytes
Isso compila com
g++ -g test.cpp -Wall -Wextra -pedantic -std=gnu++11
Talvez eu possa encurtar um pouco mais. Se você tiver algumas sugestões, por favor, comente.
fonte