Faça um intérprete 3var!

24

3var é uma variante de peixe morto que usa três variáveis ​​chamadas A, B e R. A e B são acumuladores, enquanto R é usado como variável de resultado.

Nesse desafio do , você precisa criar um intérprete para uma versão simplificada desse idioma.

Comandos necessários:

i   Increments A
d   Decrements A
s   Squares A
p   Prints A
P   Prints the ASCII character of A
>   Sets A to R
a   Increments B
k   Decrements B
m   Squares B
o   Prints B
O   Prints the ASCII character of B
<   Sets B to R
+   Adds A and B, stores in R
-   Subtracts B from A, stores in R
*   Multiplies A and B, stores in R
/   Divides A by B, stores in R
w   Prints R
@   Resets A to 0
#   Resets B to 0
e   Resets R to 0

Todo o resto (incluindo espaços em branco) é ignorado.

Esclarecimentos

  • oe pdeve sair sem nada depois dele.
  • Divisão é divisão inteira.
  • Números acima de 255 e números abaixo de 0 são suportados.
  • 'w' deve gerar um espaço ou uma nova linha após R
  • A divisão por 0 pára sem erros. (Nenhuma saída para STDERR)
  • A, B e R são inicialmente 0

Regras

  • Isso é então a resposta mais curta vence.
  • Em caso de empate, a resposta mais antiga vence.
  • O arquivo será fornecido por meio de argumentos de linha de comando ou STDIN.
  • Qualquer idioma é permitido.
  • Eval é permitido.

Casos de teste

Hello world! (retirado de Esolangs)

iisssaa/>e
maa->e#
aamam->e#
dddddddddddddddddddddddddPiiiiiiiiiiiiiiiiiiiiiiiii
iiiiPiiiiiiiPPiiiP
@#e
iis
aamaaaa
*>P
@#e
iisssaa/>e
maa->e#
aamam->e#
iiiiiiiiiiiiiiiiiiiiiiP
ddddddddP
iiiP
ddddddP
ddddddddP
@#e
iiss
aa*>
iP

Saídas 20spooky22me:

iipois+iis<-<aaaO<OkOOkkkkOP@#iippisa+<m+>PaO

Saídas 9P-1420 100 3Q-1 162 0:

iiispsdPkokmo/w<+w#aaaommO-w@ii*wew

Classificação

Aqui está um snippet de pilha para gerar uma classificação regular e uma visão geral dos vencedores por idioma.

Para garantir que sua resposta seja exibida, inicie-a com um título, usando o seguinte modelo de remarcação:

# Language Name, N bytes

onde Nestá o tamanho do seu envio. Se você melhorar sua pontuação, poderá manter as pontuações antigas no título, identificando-as. Por exemplo:

# Ruby, <s>104</s> <s>101</s> 96 bytes

Se você quiser incluir vários números no cabeçalho (por exemplo, porque sua pontuação é a soma de dois arquivos ou você deseja listar as penalidades do sinalizador de intérpretes separadamente), verifique se a pontuação real é o último número no cabeçalho:

# Perl, 43 + 2 (-p flag) = 45 bytes

Você também pode transformar o nome do idioma em um link que será exibido no snippet do placar de líderes:

# [><>](http://esolangs.org/wiki/Fish), 121 bytes

var QUESTION_ID=63008,OVERRIDE_USER=45220;function answersUrl(e){return"http://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"http://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&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(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.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(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <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><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><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>

DJgamer98
fonte
11
@ Sp3000 Por falar nisso, recentemente ajudei a corrigir um bug de loop aninhado no intérprete.
precisa
2
Esclarecimentos adicionais para pessoas familiarizadas com Deadfish: dddddpresultados em -5 e iiiisspresultados em 256 conforme o esperado, em vez de 0. #
Sp3000 5/15
11
No caso de teste Que dose rfaz? não incluídos em sua lista de comandos válidos
JimmyJazzx
11
@JimmyJazzx O testcase agora está editado, mas na linguagem 3var completa redefine tudo. É o mesmo que @#e.
precisa saber é o seguinte
11
A, B e R são inicializados como 0 quando o intérprete é iniciado?
Tony Ennis

Respostas:

7

CJam, 112

q{"+-*/dspP>@ikmoO<#awe"_@#\4<"X2 U|{TU :V;}P?"S/f*'T"( _*T cT;V;0)"2/f+":T;"f+_'Tf/'Uf*+"VS 0:V; "S/++=~}%Pa/0=

Experimente online

Explicação:

O programa cria uma matriz de partes de código a serem executadas e executa a parte correspondente para cada caractere. Lidar com a divisão por zero é mais difícil, porque o CJam ainda não possui um operador de "interrupção". Em vez disso, o programa envia π como um marcador (já que nenhum número de ponto flutuante pode aparecer de outra forma) e, no final, mantém apenas a saída antes do primeiro π.
Além disso, o programa usa as variáveis ​​T, U e V em vez de A, B e R, porque são pré-inicializadas com 0 no CJam.

q            read the input
{…}%         transform each character
  "…"        push a string with all the 3var commands, in a convenient order
  _@         duplicate the string and bring the current character to the top
  #          find the index of the character in the string (or -1 if not found)
  \          swap with the other string copy
  4<         keep only the first 4 characters ("+-*/")
  "…"        push a string that will be used for implementing those operators
  S/         split by space into ["X2" "U|{TU" ":V;}P?"]
  f*         join with each of '+', '-', '*', '/' -> 4 strings
  'T         push the 'T' character
  "…"        push a string with implementations of commands involving A
  2/         split into pieces of length 2
  f+         prepend 'T' to each piece
  ":T;"f+    append ":T;"to each piece
  _          duplicate the array (containing full A-command implementations)
  'Tf/       split each piece by the 'T' character
  'Uf*       join each split piece using the 'U' character
              practically replacing 'T' with 'U'
              to obtain B-command implementations
  +          concatenate the 2 arrays
  "…"        push a string containing implementations for "w" and "e", 
              separated by space; the string also ends with a space
  S/         split by space, obtaining the implementations for "w" and "e"
              and an empty string, for handling unrecognized characters
  ++         concatenate with the A and B command and +-*/ implementations
  =          get the corresponding string implementing the current command
              if the character was not found, -1 will get the empty string (no-op)
  ~          execute it
Pa/          split the array of results by the π separator
0=           get the first piece (before the first π, if any)

As implementações de comando reais (construídas pelo programa):

+: X2+U|{TU+:V;}P?    if (1+2)|U != 0, set V=T+U, else push π
-: X2-U|{TU-:V;}P?    if (1-2)|U != 0, set V=T-U, else push π
*: X2*U|{TU*:V;}P?    if (1*2)|U != 0, set V=T*U, else push π
/: X2/U|{TU/:V;}P?    if (1/2)|U != 0, set V=T/U, else push π
d: T( :T;             set T=T-1
s: T_*:T;             set T=T*T
p: TT :T;             push T and set T=T (no-op)
P: TcT:T;             push T converted to character and set T=T (no-op)
>: T;V:T;             push and pop T (no-op) and set T=V
@: T;0:T;             push and pop T (no-op) and set T=0
i: T):T;              set T=T+1
k: U( :U;             set U=U-1
m: U_*:U;             set U=U*U
o: UU :U;             push U and set U=U (no-op)
O: UcU:U;             push U converted to character and set U=U (no-op)
<: U;V:U;             push and pop U (no-op) and set U=V
#: U;0:U;             push and pop U (no-op) and set U=0
a: U):U;              set U=U+1
w: VS                 push V and a space
e: 0:V;               set V=0
(default): (empty)    no-op
aditsu
fonte
10

JavaScript (ES7) 208 213 223 237 241 311

Edit3 Copiando um ao outro, eu e o Dendrobium estamos entrando em colapso.

Edit2 Usando o EcmaScript 7 para salvar apenas 2 bytes, o tratamento unido de A e B

Editar Após as alterações das regras.

Observe que adicionei o rcomando que não é necessário na pergunta, apenas para executar o exemplo antigo Olá mundo

V=p=>(o='',[for(c of'@#e'+p)eval('++x,--x,x*=x,x=R,x=0,o+=x,o+=String.fromCharCode(x),R=A+B,R=A-B,R=A*B,R=A/B|0,R=0,o+=R+` `'.replace(/x/g,(k='ids>@pP+-*/ewakm<#oO'.indexOf(c))<13?'A':'B').split`,`[k%13])],o)

// More readable
U=p=>(
  o='',
  [for(c of'@#e'+p)
   eval(
   '++x,--x,x*=x,x=R,x=0,o+=x,o+=String.fromCharCode(x),R=A+B,R=A-B,R=A*B,R=A/B|0,R=0,o+=R+` `'
   .replace(/x/g,(k='ids>@pP+-*/ewakm<#oO'.indexOf(c))<13?'A':'B')
   .split`,`[k%13])]
  ,o
)

// ES6, no array comprehension, 2 bytes more
W=p=>
  [...'@#e'+p].map(c=>
    eval(
    '++x,--x,x*=x,x=R,x=0,o+=x,o+=String.fromCharCode(x),R=A+B,R=A-B,R=A*B,R=A/B|0,R=0,o+=R+` `'
    .replace(/x/g,(k='ids>@pP+-*/ewakm<#oO'.indexOf(c))<13?'A':'B')
    .split`,`[k%13]),
    o=''
  )&&o

// Test
function test() 
{ 
  OUT.innerHTML = V(I.value) 
}

test()
textarea { width: 75%; height: 8em }
Test program <button onclick="test()">Run</button><br><textarea id=I>
iisssaa/>e
maa->e#
aamam->e#
dddddddddddddddddddddddddPiiiiiiiiiiiiiiiiiiiiiiiii
iiiiPiiiiiiiPPiiiP
@#e
iis
aamaaaa
*>P
@#e
iisssaa/>e
maa->e#
aamam->e#
iiiiiiiiiiiiiiiiiiiiiiP
ddddddddP
iiiP
ddddddP
ddddddddP
@#e
iiss
aa*>
iP
</textarea><br>Output<pre id=OUT></pre>

edc65
fonte
Você poderia salvar 2 bytes através da remoção A=B=R=0,e definindo essas variáveis usando as reais 3var funções antes de processar a string, como: [...'@#e'+p].
usar o seguinte comando
2
@insertusernameaqui thx, eu amo esse aqui
edc65
8

GNU Sed (com opção de avaliação para avaliar a dcexpressão), 254

O Deadfish mapeia bastante bem para um subconjunto de dc. Então, usamos sed para fazer esse mapeamento:

s/^/@#e/
s/\+/AB+r/g
s/-/AB-r/g
s/\*/AB*r/g
s|/|AB/r|g
s/a/B1+b/g
s/i/A1+a/g
s/d/A1-a/g
s/s/Ad*a/g
s/p/An/g
s/P/AP/g
s/>/Ra/g
s/k/B1-b/g
s/m/Bd*b/g
s/o/Bn/g
s/O/BP/g
s/</Rb/g
s/w/Rn/g
s/@/0a/g
s/#/0b/g
s/e/0r/g
s/[ABR]/l&/g
s/[abr]/s\u&/g
s/.*/dc -e'&'/e
Trauma Digital
fonte
8

Javascript ES6 ES7, 217 215 213 208 bytes

f=s=>(O='',[for(c of'@#e'+s)eval('v=0,++v,--v,v*=v,O+=v,O+=String.fromCharCode(v),v=R,R=0,R=A+B,R=A-B,R=A*B,R=A/B|0,O+=R+" "'.replace(/v/g,'AB'[(x='@idspP>e+-*/w#akmoO<'.indexOf(c))/13|0]).split`,`[x%13])],O)

Ungolfed

f=s=>(
    O='',                                                                   // initialize output to empty string
    [for(c of'@#e'+s)eval(                                                  // initialize A, B, and R, loop over all chars in input, eval returned function string
        'v=0,++v,--v,v*=v,O+=v,O+=String.fromCharCode(v),v=R,R=0,R=A+B,R=A-B,R=A*B,R=A/B|0,O+=R+" "' // operation list
            .replace(/v/g,'AB'[(x='@idspP>e+-*/w#akmoO<'.indexOf(c))/13|0]) // replace all instances of v with either A or B
            .split`,`[x%13])],                                              // split ops list, select corresponding function string
    O)                                                                      // return output string
Dendrobium
fonte
11
+1 Não muito longe do meu, mas melhor. Agora eu vou ter que tentar algo diferente
edc65
11
Você poderia salvar 2 bytes através da remoção A=B=R=0,e definindo essas variáveis usando as reais 3var funções antes de processar a string, como: for(c of '@#e'+s).
usar o seguinte comando
11
@insertusernamehere Aha, isso é muito inteligente, obrigado!
Dendrobium
Rever a sua resposta, eu vejo que você não saída uma nova linha de comandow
edc65
@ edc65 Um dos marcadores de esclarecimento afirma que "'w' deve gerar um espaço ou uma nova linha após R"
Dendrobium
6

APL, 191

{0::→⋄A B R←0⋄{⍵∊G←'aikdms<>':⍎'AB'[1+2|G⍳⍵],'+-*∘'[M],'←','112R'[M←⌈2÷⍨G⍳⍵]⋄⍵∊G←'PpOo':⍞←⎕UCS⍣(2|G⍳⍵)⊢A B[⌈2÷⍨G⍳⍵]⋄⍵∊G←'+-*/':R∘←⌊A(⍎'+-×÷'[G⍳⍵])B⋄⍵∊G←'@#e':⍎'ABR'[G⍳⍵],'∘←0'⋄⍵='w':⍞←R}¨⍵}

Esta é uma função que aceita o programa como argumento, por exemplo:

      ∆3var←{0::→⋄A B R←0⋄{⍵∊G←'aikdms<>':⍎'AB'[1+2|G⍳⍵],'+-*∘'[M],'←','112R'[M←⌈2÷⍨G⍳⍵]⋄⍵∊G←'PpOo':⍞←⎕UCS⍣(2|G⍳⍵)⊢A B[⌈2÷⍨G⍳⍵]⋄⍵∊G←'+-*/':R∘←⌊A(⍎'+-×÷'[G⍳⍵])B⋄⍵∊G←'@#e':⍎'ABR'[G⍳⍵],'∘←0'⋄⍵='w':⍞←R}¨⍵}
      ∆3var 'iipois+iis<-<aaaO<OkOOkkkkOP@#iippisa+<m+>PaO'
20spooky22me

Pode ser usado como uma função anônima, apenas dei um nome para maior clareza.

Explicação:

  • 0::→: se ocorrer um erro (por exemplo, divisão por zero), pare sem imprimir a mensagem de erro
  • A B R←0: inicializar variáveis
  • {... }¨⍵: para cada comando:

    • ⍵∊G←'aikdms<>': Se o comando for do tipo var ← fn (var, x) , encontre os fn e x adequados , substitua-os e avalie-os:
      • : Avalie
      • 'AB'[1+2|G⍳⍵: Ase a posição de in 'aikdms<>'for par, Bcaso contrário.
      • '+-*∘'[M]: adicionar, subtrair, energia ou nada, dependendo de M(definido posteriormente)
      • '←': atribuir
      • '112R'[M←⌈2÷⍨G⍳⍵]: 1(para adicionar e subtrair), 2(para poder) e R(para nada, ou seja, apenas define a variável para R), dependendo de Mqual seja o comando pertencer ao primeiro, segundo, terceiro ou quarto par.
    • ⍵∊G←'PpOo': saída:
      • ⍞←: saída
      • ⎕UCS⍣(2|G⍳⍵): ASCII (bem, Unicode) ou número, dependendo de o comando estar em uma posição ímpar ou par PpOo,
      • ⊢A B[⌈2÷⍨G⍳⍵]: Aou B, dependendo se o comando foi no primeiro ou no segundo semestre.
    • ⍵∊G←'+-*/: math:
      • R∘←⌊A(⍎'+-×÷'[G⍳⍵])B: defina Ro resultado da aplicação do operador especificado em Ae B.
    • ⍵∊G←'@#e': restabelecer:

      • : Avalie
      • 'ABR'[G⍳⍵]: selecione a variável correta
      • '∘←0': definido como zero
    • ⍵='w':⍞←R: se o comando for w, output R.

marinus
fonte
4

C, 253 241 bytes

#define _ c--?c--?c--
k="id@s>ak#m<e+-*/wpoPO",*p;main(c,a,b,r){for(a=b=r=0;~c;c=getchar())c=strchr(k,c),c&&(c-=k,p=&a+c/5,*p=_?_?_?_?_?printf(c?c<3?"%d":"%c":"%d ",c?c%2?a:b:r):a/(b?b:exit()):a*b:a-b:a+b:0:r:b*b:0:b-1:b+1:r:a*a:0:a-1:a+1);}

Este código usa a string id@s>ak#m<e+-*/wpoPOcomo uma tabela de comandos. A sequência é organizada de acordo com o destino da expressão calculada. Acontece que existem 5 comandos que atualizam cada uma das variáveis:

  • id@s> - atualização a
  • ak#m< - atualização b
  • e+-*/ - atualização r
  • wpoPO- update ... a localização de memória depois de a, be r. Espero que não seja muito importante :)

Portanto, após localizar o caractere de entrada na sequência de comandos, seu índice diminui repetidamente e, dependendo de quando atingir 0, uma expressão é escolhida.

Se não atingir 0 após 15 subtrações, é uma printf argumento com alguns escolhidos corretamente.

Além disso, ao dividir, evita a divisão por 0 chamando exit() .

Esse código deve ser compilado sem otimizações, pois assume que a, ber estão localizados em endereços adjacentes na pilha (e não em registros de CPU).

Além disso, ele deve ser compilado no modo de 32 bits, porque converte ponteiros em números inteiros e vice-versa.

anatolyg
fonte
4

VBA, 484, 453 380 bytes

Anseio por vencer, mas Uma maneira super simples de fazer as coisas, Nada Gosta apenas de bons velhos Select Case

Adição de divisão de número inteiro e tratamento de erros da Div 0 Comeram muitos bytes
removidos, pois parece que o tratamento normal de erros resulta na mesma funcionalidade. Divisão Int fixa para funcionar como esperado. Também foi mais curto.

Function Y(x)
For Z=1 To Len(x)
w=Mid(x,Z,1)
Select Case w
Case"i":A=A+1
Case"d":A=A-1
Case"s":A=A^2
Case"p":Y=Y &A
Case"P":Y=Y &Chr(A)
Case">":A=R
Case"a":B=B+1
Case"k":B=B-1
Case"m":B=B^2
Case"o":Y=Y &B
Case"O":Y=Y &Chr(B)
Case"<":B=R
Case"+":R=A+B
Case"-":R=A-B
Case"*":R=A*B
Case"/":R=A\B
Case"w":Y=Y &R &vbCrLf
Case"@":A=0
Case"#":B=0
Case"e":R=0
End Select
Next
End Function

Agradecimentos a Henrik Ilgen por salvar 31 104 bytes

JimmyJazzx
fonte
2
Não inteiramente certo se isso funciona em VBA (que faz em VB6), mas você pode salvar um monte de bytes usando DefInt A-Z, omitindo assim a necessidade de declarar explicitamente A, Be Rcomo Integer: DefInt A-Z:Dim A, B, R. Ele poderia muito bem trabalhar apenas para atribuir-lhes, sem declaração: A=0:B=0:R=0. Os cálculos também devem funcionar com variantes.
Henrik Ilgen
@ HenrikIlgen muito obrigado, Esqueci o DefIntNot Something que eu uso todos os dias, mas será um VBA de golfe super útil no futuro. Infelizmente A=0, isso fará com que funcione como um dobro dos meus testes. Lá para fazer iiiaa/wproduzir um resultado decimal e não um todo.
JimmyJazzx
11
Tente \ para a divisão integer;)
Henrik Ilgen
11
Você pode condensá-lo para baixo para 405 bytes , se você faz uma função e usar o valor de retorno para "construir" o resultado, supondo que você não tem que realmente imprimir o resultado :)
Henrik Ilgen
3

PHP, 310 bytes

Primeira vez na minha vida usando eval:

for($A=$B=$R=0;$c=$argv[1][$i++];)eval([i=>'++$A',d=>'--$A',s=>'$A*=$A',p=>'echo$A',P=>'echo chr($A)','>'=>'$A=$R',a=>'++$B',k=>'--$B',m=>'$B*=$B',o=>'echo$B',O=>'echo chr($B)','<'=>'$B=$R','+'=>'$R=$A+$B','-'=>'$R=$A-$B','*'=>'$R=$A*$B','/'=>'$R=$A/$B',w=>'echo$R','@'=>'$A=0','#'=>'$B=0',e=>'$R=0'][$c].';');

Toma a primeira entrada da linha de comando:

php 3var.php "iipois+iis<-<aaaO<OkOOkkkkOP@#iippisa+<m+>PaO"

Saída dos exemplos:

Olá Mundo!
20spooky22me

insertusernamehere
fonte
3

C, 357

Macros FTW!

(Quem eu estou brincando - c nunca vai ganhar este)

#define X(p,e) case p:e;break;
#define Y(p,a,b,c,d,e,f) X(a,p++)X(b,p--)X(c,p*=p)X(d,printf("%d",p))X(e,printf("%c",p%256))X(f,p=R)
A,B,R;main(int C,char**V){for(;*V[1];)switch(*V[1]++){Y(A,'i','d','s','p','P','>')Y(B,'a','k','m','o','O','<')X('+',R=A+B)X('-',R=A-B)X('*',R=A*B)X('/',R=A/(B?B:exit(0),1))X('w',printf("%d",R))X('@',A=0)X('#',B=0)X('e',R=0)}}
Trauma Digital
fonte
2

JavaScript (ES6), 293 262 bytes

f=x=>(o="",a=b=r=0,p=String.fromCharCode,[...x].map(c=>{if(eval(`m={i_a++,d_a--,s_a*=a,p_o+=a,P_o+=p(a),">"_a=r,a_b++,k_b--,m_b*=b,o_o+=b,O_o+=p(b),"<"_b=r,"+"_r=a+b,"-"_r=a-b,"*"_r=a*b,"/"_r=a/b|0,w_o+=r,"@"_a=0,"#"_b=0,e_r=0}[c]`.replace(/_/g,":_=>")))m()}),o)

Uso

f(`iisssaa/>e
maa->e#
aamam->e#
dddddddddddddddddddddddddPiiiiiiiiiiiiiiiiiiiiiiiii
iiiiPiiiiiiiPPiiiP
@#e
iis
aamaaaa
*>P
@#e
iisssaa/>e
maa->e#
aamam->e#
iiiiiiiiiiiiiiiiiiiiiiP
ddddddddP
iiiP
ddddddP
ddddddddP
@#e
iiss
aa*>
iP`)

=> "Hello world!"

Explicação

Existem alguns detalhes do idioma sobre o qual não tenho certeza (tamanhos inteiros, manipulação de caracteres não reconhecidos etc.), mas essa solução parece funcionar o suficiente e ignora caracteres de espaço em branco como as novas linhas no caso de teste.

f=x=>(
  o="",                           // o = output string
  a=b=r=0,
  p=String.fromCharCode,
  [...x].map(c=>{                 // iterate through each character
    if(                           // if used for NOP characters (whitespace)

      // Functions:
      eval(`m={
        i_a++,
        d_a--,
        s_a*=a,
        p_o+=a,
        P_o+=p(a),
        ">"_a=r,
        a_b++,
        k_b--,
        m_b*=b,
        o_o+=b,
        O_o+=p(b),
        "<"_b=r,
        "+"_r=a+b,
        "-"_r=a-b,
        "*"_r=a*b,
        "/"_r=a/b|0,
        w_o+=r,
        "@"_a=0,
        "#"_b=0,
        e_r=0
      }[c]`.replace(/_/g,":_=>")) // dynamically add common characters

    )m()                          // execute the function
  }),
  o                               // return the output string
)
user81655
fonte
11
Eu acho que você pode economizar alguns bytes colocando o dicionário em uma avaliação enquanto substitui todos :$=>por $e adicionando uma substituição para a string.
Conor O'Brien
2

Simplex v.0.8 , 211 bytes

(Codificado em UTF-8.)

h@u]u2ƒ§I]ƒ§M]ƒ§^O]ƒ§o]ƒ§s]ƒ§@]ƒ§Ah]ƒ§Sh]ƒ§Mh]ƒ§Vh]ƒ§&oh]ƒðI]ƒðM]ƒð^O]ƒðo]ƒðs]ƒð@]ƒðAh]ƒðSh]ƒðMh]ƒðVh]ƒð&oh]ƒ§z]ƒðz]ƒuz@]{"idspP>akmoO<+-*/w@#e"RlyG^u·u†vøÏ}

Explicação

Como esse é o programa simplex mais longo que eu escrevi até agora, geralmente explicarei como isso funciona nos tópicos.

  • h@u] - define a macro 0. Essa macro simplesmente grava no registrador e faz com que um lambda não retorne nada.
  • u2- vai para a faixa acima e define o byte atual como 2; isso define a aridade das lambdas a serem definidas.
  • ƒ- começa a expressão lambda; uma vez concluído ], empurrará a função lambda para a pilha lambda. Ele age levando as células (de área) do ponteiro para sua faixa local e, após a conclusão, definirá sua faixa local para as células obtidas, a menos que o byte atual não seja gravado. O ponteiro não é afetado. A macro 0 permite que uma função retorne sem modificar nada na faixa.
  • §- move para a primeira célula escrita na faixa atual, ie A.
  • ð- move para a última célula gravada na faixa atual, ie B.
  • ... {"idspP>akmoO<+-*/w@#e"RlyG^u·u†vøÏ}
    • {...Ï} repita até a pilha de entrada estar vazia
    • "idspP>akmoO<+-*/w@#e" - os comandos
    • Rly - coloque a tira em uma tupla
    • G^u - o índice da entrada na tupla
    • ·- carrega o byte th atual no avaliador lambda
    • uRL- vai para a faixa segurando Ae B(escreve Ae Bse não existir)
    • - executa lambda (este é o avaliador lambda)
    • - redefine abaixo da faixa

ufa , estou impressionado. É longo para o Simplex, mas curto para todo o resto.;)

Conor O'Brien
fonte
2

Minkolang 0.11 , 222 bytes

Tenho certeza de que isso pode ser jogado ainda mais, mas foi divertido. Além disso, primeiro intérprete de Minkolang de outro idioma!

>I3&000V$Vod?.45*[di1q=5&]x00wx1i2+kw
idspP>akmoO<+-*/w@#e
vr1+r
vr1-r
vr2;r
v0c1$((dl%"0"+$rl:d)$Ok
v0cO
vrx0cr
v1g1+1G
v1g1-1G
v1g2;1G
v1c1$((dl%"0"+$rl:d)$Ok
v1cO
v1gxd1G
vx$d+
vx$d-
vx$d*
vx$dd?.:
vdN
vrx0r
v1gx01G
vx0

Experimente aqui.

Explicação

>I3&000                    Initializes A, B, and R if they don't already exist.
V$V                        An idiom that ensures no time-travel.
od?.                       Reads in a character and halts if input is empty.
45*[di1q=5&]               Looks through the second row for a matching character.
            x00w           Jumps back to beginning if no match.
                x1i2+kw    Jumps to corresponding line upon match.

O restante das linhas é bem simples, talvez com exceção das que estão com 1$((dl%"0"+$rl:d)$Ok, que é um idioma que imprime um número sem deixar espaço. (Ainda não implementei a funcionalidade converter esse número em uma string, que será 1Z.) Ah, sim, todos eles têm um vno início, o que o leva de volta ao início.

El'endia Starman
fonte
2

GNU Sed (com opção de avaliação para avaliar a expressão dc), 289

Inspirado pelo Digital Trauma que infelizmente não conseguiu perceber, que a) caracteres ilegais precisam ser ignorados, b) dc precisa de todo o programa convertido em um argumento ec) divisão por 0 deve encerrar o programa sem erros.

Se todas essas regras não se aplicassem, minha solução teria apenas 235 bytes;)

H
$!d
x
s/^/@#e/
s:[^-a><de/+i*k@w#opsmOP]::g
s:[e@#]:0&:g
s:[-*+/pPid]:Q&:g
s:[-kaoO*+/]:H&:g
s:[><w]:Z&:g
s:[diak]:1&:g
s:s:Q2^>:g
s:m:H2^<:g
s:[-+*/]:&e:g
s:[ia]:+&:g
s:[dk]:-&:g
y:Oop:Pnn:
s:w:n32P:g
s:[id>@]:sq:g
s:e:sz:g
s:[#<ka]:sh:g
s:[QHZ]:l\l&:g
s:/:d0=t/:g
s/.*/dc -e'[q]st&'/e
Bodo Thiesen
fonte
2

AWK, 311 309

func p(z,f,x){if(c~z)printf"%"f,x}BEGIN{FS=z}{for(i=0;++i<=NF;){c=$i;A=c~/i/?A+1:c~/d/?A-1:c~/s/?A*A:c~/@/?0:c~/>/?R:A;p("p","d",A);p("P","c",A);B=c~/a/?B+1:c~/k/?B-1:c~/m/?B*B:c~/#/?0:c~/</?R:B;p("o","d",B);p("O","c",B);R=c~/+/?A+B:c~/-/?A-B:c~/*/?A*B:c~/e/?0:R;if(c~"/")if(B)R=A/B;else exit;p("w","d ",R)}}

Parênteses TIL não eram necessários em torno do printf. 2 bytes salvos!

Versão não destruída para facilitar a leitura:

func p(z,f,x) {
    if(c~z) printf "%"f,x
}

BEGIN {
    FS=z
}

{
    for(i=0;++i<=NF;){
        c=$i;
        A=c~/i/?A+1:c~/d/?A-1:c~/s/?A*A:c~/@/?0:c~/>/?R:A;
        p("p","d",A);
        p("P","c",A);
        B=c~/a/?B+1:c~/k/?B-1:c~/m/?B*B:c~/#/?0:c~/</?R:B;
        p("o","d",B);
        p("O","c",B);
        R=c~/+/?A+B:c~/-/?A-B:c~/*/?A*B:c~/e/?0:R;
        if(c~"/")if(B)R=A/B;else exit;
        p("w","d ",R)
    }
}
LeFauve
fonte
1

Python 2, 272

import sys;a,b,r=0,0,0;exec';'.join(filter(None,map(dict(x.split(':')for x in"a:b+=1|@:a=0|#:b=0|/:r=a/b|d:a-=1|PXchr(a)|i:a+=1|-:r=a-b|k:b-=1|*:r=a*b|m:b*=b|oXb|pXa|s:a*=a|OXchr(b)|wXr|+:r=a+b|e:r=0|<:b=r|>:a=r".replace('X',':print ').split('|')).get,sys.stdin.read())))
dieter
fonte
Isso não funciona. Suas printdeclarações incluem uma nova linha à direita.
Griffin
1

Ruby, 199 bytes

a=b=r=0
$<.read.chars{|c|eval %w{a+=1
a-=1
a*=a
$><<a
$><<a.chr
a=r
b+=1
b-=1
b*=b
$><<b
$><<b.chr
b=r
r=a+b
r=a-b
r=a*b
b==0&&exit||r=a/b
puts\ r
a=0
b=0
r=0
p}["idspP>akmoO<+-*/w@#e".index(c)||-1]}

É possível salvar 5 bytes removendo .readda segunda linha se você puder tolerar que um aviso seja impresso no stderr na versão mais recente do Ruby.

daniero
fonte
1

Python, 244

import sys;P=sys.stdout.write;A=B=R=0;exec';'.join(filter(None,map(dict(zip('idspP>akmoO<+-*/w@#e','A+=1 A-=1 A**=2 P(`A`) P(chr(A)) A=R B+=1 B-=1 B**=2 P(`B`) P(chr(B)) B=R R=A+B R=A-B R=A*B R=A/B print(R) A=0 B=0 R=0'.split())).get,input())))

Um pouco tarde, mas eu queria tentar.

Griffin
fonte
1

Prolog, 759 bytes

Não é o programa mais curto, mas pelo menos é estruturado e legível.

q(A,B,R,i,X,B,R):-X is A+1.
q(A,B,R,d,X,B,R):-X is A-1.
q(A,B,R,s,X,B,R):-X is A*A.
q(_,B,R,>,R,B,R).
q(A,B,R,a,A,X,R):-X is B+1.
q(A,B,R,k,A,X,R):-X is B-1.
q(A,B,R,m,A,X,R):-X is B*B.
q(A,_,R,<,A,R,R).
q(A,B,_,+,A,B,X):-X is A+B.
q(A,B,_,-,A,B,X):-X is A-B.
q(A,B,_,*,A,B,X):-X is A*B.
q(_,0,_,/,_,_,_):-!,1=2.
q(A,B,_,/,A,B,X):-B>0,X is A/B.
q(_,B,R,@,0,B,R).
q(A,_,R,#,A,0,R).
q(A,B,_,e,A,B,0).
q(A,B,R,p,A,B,R):-write(A).
q(A,B,R,'P',A,B,R):-A>0,format('~c',A).
q(A,B,R,'P',A,B,R):-write(A).
q(A,B,R,o,A,B,R):-write(B).
q(A,B,R,'O',A,B,R):-format('~c',B).
q(A,B,R,'O',A,B,R):-write(B).
q(A,B,R,w,A,B,R):-write(R),nl.
q(A,B,R,_,A,B,R).
f([],_,_,_).
f([H|T],A,B,R):-q(A,B,R,H,X,Y,Z),f(T,X,Y,Z),!.
p(X):-atom_chars(X,Y),f(Y,0,0,0).

Exemplo de entrada

p('iipois+iis<-<aaaO<OkOOkkkkOP@#iippisa+<m+>PaO').

Experimente online aqui

Emigna
fonte