Escreva um intérprete interativo do Deadfish

30

Deadfish é uma piada "linguagem de programação" com quatro comandos. Como a página Esolang é um pouco contraditória e os intérpretes dessa página não funcionam exatamente da mesma maneira, você deve implementar a seguinte variação:


Especificação

  1. Existe um acumulador que tem pelo menos 16 bits de tamanho, mais é permitido, mas menos não. Números negativos não precisam ser suportados. O acumulador é 0quando o programa é iniciado.
  2. Existem os dois conjuntos a seguir de quatro comandos, e seu programa deve suportar os dois ao mesmo tempo.
      Peixe morto padrão │ Variante XKCD │ Significado
      ─────────────────────────────────────────────────────── ───────────────────────────
            i │ x │ Acumulador de incremento
            d │ d accum Decremento acumulador
            s │ k │ Quadrado (acc = acc * acc)
            o │ c │ Acumulador de saída, como um número
    
  3. Se, após executar um comando, o acumulador for -1ou 256, o acumulador deverá ser redefinido para zero. Observe que isso não é normal. Se, por exemplo, o acumulador estiver 20e o scomando for executado, o acumulador deverá ser 400posterior. Da mesma forma, se o acumulador estiver 257e o dcomando for executado, o acumulador deverá se tornar 0.
  4. Qualquer entrada que não seja um desses comandos deve ser ignorada.

Programas de teste

  • xiskso deve produzir 0
  • xiskisc deve produzir 289

I / O

Seu programa deve exibir um aviso: >>. O prompt deve estar no início de uma nova linha. Ele deve ler uma linha de entrada do usuário e executar os comandos fornecidos da esquerda para a direita. Ao emitir números, os números devem ser separados. Ou seja, 12 34está bem, 12,34está bem,

12
34 

está OK, mas 1234não está.

Seu programa deve continuar fazendo isso em um loop, pelo menos até que EOFseja alcançado.

Sessão de exemplo:

>> xiskso
0
>> xiskisc
289
>> ddddo ddddo
285
281
>> ddddo ddddo
277
273
>> dddddddo
266
>> dddddddddo
257
>> do
0
>> do
0
>> io
1
>> 
marinus
fonte
Devido à solicitação de entrada, não posso usar o GolfScript :-(
ProgramFOX
@ProgramFOX: Você pode usar a entrada ruby, certo?
marinus
De acordo com o tutorial do GolfScript, você não pode solicitar a entrada no GolfScript, toda a entrada vem do STDIN.
precisa
@ProgramFOX: Eu teria pensado que algo assim #{STDIN.gets}funcionaria, mas na verdade não funciona.
marinus
Em vez disso, é permitido receber entradas com letras maiúsculas?
lirtosiast

Respostas:

6

K, 77 bytes

  {1">>";0{x*2=-1 256?x:y@x}/("xkcdiso"!7#(1+;{x*x};{-1@$x;x};-1+))@0:0;.z.s`}`
>>xiskso
0
>>xiskisc
289

Note que este é o K4 . Uma solução K6 é um pouco mais longa porque os verbos de E / S são mais longos, mesmo que tudo o resto seja melhor:

{""0:">>";0{x*^-1 256?x:y@x}/("xkcdiso"!7#(1+;{x*x};{""0:,$x;x};-1+))@0:"";o`}`
  • ""0:imprime e retorna seu argumento. Observe no K4 que simplesmente aplicamos a 1 .
  • 0 f/ args demonstra redução com um valor inicial, ou seja, f[f[0;first arg];second arg]…
  • {x*2=-1 256?x…classifica x em 0 (para -1), 1 (para 256) e 2 para todos os outros valores. 2=significa que obtemos 1valores não classificados e 0, caso contrário, multiplicar por xé mais curto que um condicional. No K6, podemos melhorar um pouco porque {x*^-1 256?x:y@x}confia no fato de -1 256?xretornar 0N(nulo) e ^detectar nulos.
  • O "analisador" é o mapa em "xkcdiso"vez da ordem sugerida, porque 7#contorna os quatro argumentos, isto é, 7#"abcd"retornos "abcdabc"que mantêm nossa tabela menor
  • O mapa traduz "x"e "i"para a projeção 1+que é equivalente à função, {1+x}mas mais curta.
  • O mapa se traduz "d"na projeção -1+que é equivalente à função, {-1+x}mas mais curta.
  • O mapa traduz "k"e "s"para a função{x*x}
  • O mapa converte "c"e "o"para a função de saída {-1@$x;x}que novamente no K6 é um pouco mais longa: {""0:,$x;x}mas ambos imprimem sua saída seguida por uma nova linha e, em seguida, retornam o argumento.
  • .zs é auto-recursão. No K6, podemos simplesmente dizer o`qual é mais curto.
geocar
fonte
8

Perl 5 , 90 bytes

do{print+(map{$?+=/i|x/-/d/;$?**=1+/s|k/;$?=~s/-1|^256$/0/;"$?
"x/o|c/}/./g),'>> '}while<>

Experimente online!

Agradecemos ao @xfix por sua ajuda nisso anteriormente! Guardado 4 bytes graças a @Xcali !

Dom Hastings
fonte
11
Seu programa é impresso 1quando o acumulador transborda. Além disso, você pode reduzir seu programa em cinco caracteres, alterando $apara $?(que é inicializado 0e não será alterado até que você execute algum programa externo a partir do Perl).
precisa
Ahhhh, eu estava procurando por uma variável que eu pudesse usar, perfeita, obrigada! Quanto ao transbordamento, eu não percebi isso, pois só acontece se você executar isssocomo um comando, não se você fizer cada um separadamente ... Vou dar uma olhada nisso mais tarde e certamente usará $?. Obrigado!
Dom Hastings
Então, acho que deixei uma versão mais antiga na seção de código na parte superior com, em ''vez disso "", quando usado com perl -e '...'o mapa terminaria com o resultado do s///. Obrigado novamente!
Dom Hastings
OK, você é o mais baixo.
Marinus
11
Não é mais a resposta mais curta.
geocar
6

Powershell, 131 126 121 114 113

for($x=0){[char[]](read-host ">>")|%{switch -r($_){"i|x"{$x++}"d"{$x-=!!$x}"s|k"{$x*=$x}"o|c"{$x}}
$x*=$x-ne256}}
  • for($x=0){...} - defina o acumulador como 0 e faça um loop para sempre
  • read-host '>>' - obtenha a entrada do usuário rapidamente >>
  • [char[]](...) - converte a entrada do usuário em uma matriz de caracteres
  • |%{...} - executar o que está dentro {} de cada personagem
  • switch -r($_) - comutador regex para cada caractere
  • "i|x"{$x++} - combinar ioux - aumentar o acumulador
  • "d"{$x-=!!$x} - match d- diminua $xpor !!$x, que será 0if $xis 0e de 1outra forma. Isso garante que o acumulador nunca chegue-1 .
  • "s|k"{$x*=$x} - combinar souk - quadrado
  • "o|c"{$x} - combinar oouc - gerar o acumulador
  • $x*=$x-ne256- multiplique o acumulador por 0se é 256ou por 1outro

Saída de exemplo

>>: xiskso
0
>>: xiskisc
289
>>: ddddo ddddo
285
281
>>: ddddo ddddo
277
273
>>: dddddddo
266
>>: dddddddddo
257
>>: do
0
>>: do
0
>>: io
1
>>:

Eu acho que a implementação de read-hosté específica do host, portanto esse host do Powershell (ConsoleHost) anexa :ao prompt especificado.

Danko Durbić
fonte
Agradável! Ame o decréscimo de !!$xvergonha, eu não posso utilizar essa ...
Dom Hastings
Ei Danko, você poderia postar alguma saída de teste, por favor? Eu não acho que eu possa testar shell poder em não-Windows ... (por favor me corrija se eu estiver errado!)
Dom Hastings
Eu adicionei alguns resultados de teste à resposta.
Danko Durbić
6

Rebol 3, 178 169 161 159

f: does [if a = -1 or (a = 256)[a: 0]]d: [any[["i"|"x"](++ a f)|["d"](-- a f)|["s"|"k"](a: a * a f)|["o"|"c"](print a)| skip]]a: 0 forever [parse (ask ">>") d]

Versão mais bonita:

f: does [if a = -1 or (a = 256) [a: 0]]
d: [
    any [
        ["i"|"x"] (++ a f) |
        ["d"] (-- a f) |
        ["s"|"k"] (a: a * a f) |
        ["o"|"c"] (print a) |
        skip
    ]
]
a: 0 
forever [parse (ask ">>") d]
kealist
fonte
6

Haskell, 202

r=pure;-1%c=0%c;256%c=0%c;s%'o'=s<$print s;s%'c'=s%'o';s%'i'=r$s+1;s%'x'=s%'i'
s%'d'=r$s-1;s%'s'=r$s^2;s%'k'=s%'s';s%_=r s;n s(c:[])=s%c;n s(c:f)=s%c>>=(`n`f)
main=p 0;p s=putStr">> ">>getLine>>=n s>>=p
Ry-
fonte
Você provavelmente poderia economizar alguns personagens mudando ee vem operadores. Eu também tentei reescrever ve gpara que o parâmetro xpermaneça no IO e printetc. seja levantado. Não consegui fazê-lo funcionar, mas acho que pode ser um bom lugar para alguém que conhece o haskell.
Shiona
@ shiona: Sim, a coisa de manter as coisas em ordem IOé que elas imprimem com muita freqüência (é por isso que eu usei em r nvez de x) ou não o suficiente, porque o valor nunca é solicitado…. Então, como eu ia mudar ee vem operadores?
Ry-
Eu tive os mesmos problemas com a impressão. O que acontece com os operadores que você pode fazer (usando e como exemplo) 'i'%x=x+1;'d'%x=x-1... E apenas chame no v do n<-x;r$w$o%n. A razão pela qual os operadores economizam espaço é que eles não exigem espaços ao seu redor.
shiona
@ shiona: Oh! Boa ligação, obrigado!
Ry-
Sem problemas. Primeiro pensei em fazer minha própria resposta, mas como não consegui colocar minhas grandes idéias em prática, pensei que seria apenas rude postar exatamente o mesmo código com apenas uma notação diferente para as mesmas funções.
Shiona
4

Ruby, 140 138

a=0
loop{$><<'>> '
eval gets.gsub(/./){|c|({i:i='a+=1',x:i,d:'a-=1',s:s='a**=2',k:s,o:o='p a',c:o}[:"#{c}"]||'')+';a=a==-1||a==256?0:a;'}}

Sessão de amostra (igual à sua):

c:\a\ruby>deadfish
>> xiskso
0
>> xiskisc
289
>> ddddo ddddo
285
281
>> ddddo ddddo
277
273
>> dddddddo
266
>> dddddddddo
257
>> do
0
>> do
0
>> io
1
>>
Maçaneta da porta
fonte
4

K, 121

i:0;while[1;1">> ";{i{(r;0)(-1~r)|256~r:y x}/d{x@&x in y}[x;!d:"ixdskoc"!,/(2#(1+);-1+;2#{x*x};2#{-1@$i::x;})]}'" "\:0:0]

.

C:\q>q deadfish.k -q
>> xiskso
0
>> xiskisc
289
>> ddddo ddddo
285
281
>> ddddo ddddo
277
273
>> dddddddo
266
>> dddddddddo
257
>> do
0
>> do
0
>> io
1
>>
tmartin
fonte
Minha versão é mais curta. Eu comprimi o mapa, confiei ? para classificar os valores de "quebra automática", usou recursão em vez de enquanto e um intérprete funcional em vez de emendar.
geocar
4

Ada

Aqui está uma implementação Ada para os poucos interessados ​​neste idioma. Levei algum tempo para usar algumas das melhores práticas de Ada (como o uso de Indefinite_Holders em vez de acessar) e também para entender completamente como o Deadfish deve funcionar.

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Containers.Indefinite_Holders;
with Ada.Integer_Text_IO;

procedure Deadfish is
   package String_Holder is new Ada.Containers.Indefinite_Holders(String);
   use String_Holder;

   value_output : Natural := 0;
   str_input : String_Holder.Holder := To_Holder("");
begin
   Prompt :
   loop
      Put(">> ");
      String_Holder.Replace_Element(str_input, Get_Line);
      for rg in str_input.Element'Range loop
         case str_input.Element(rg) is
            when 'i' | 'x' => 
               case value_output is
                  when 255 => value_output := 0;
                  when others => value_output := Natural'Succ(value_output);
               end case;

            when 'd'       =>                   
               case value_output is
                  when 257 => value_output := 0;
                  when 0 => null;
                  when others => value_output := Natural'Pred(value_output);
               end case;
            when 's' | 'k' => 
               case value_output is
                  when 16 => value_output := 0;
                  when others =>value_output := value_output * value_output;
               end case;
            when 'o' | 'c' => Ada.Integer_Text_IO.Put(value_output, Width => 0); Put_Line("");
            when others => null;
         end case;
      end loop;
   end loop Prompt;
end Deadfish;

E a saída:

>> xiskso
0
>> xiskisc
289
>> ddddo ddddo
285
281
>> ddddo ddddo
277
273
>> dddddddo
266
>> dddddddddo
257
>> do
0
>> do
0
>> io
1
>>

Se algumas pessoas que experimentaram Ada pudessem me dar algumas dicas de otimização, ficaria agradecido.

Jérémy Ruelle
fonte
11
Bem-vindo ao PPCG! O objetivo do code-golf é criar o código mais curto possível, e você deve incluir o tamanho do seu programa no cabeçalho (1396 bytes aqui)
TuxCrafting
4

C, 159 caracteres

A; main(c) {
  printf(">> ");
  while (c = getchar(), ~c)
    A = c - 'i' & c - 'x'?
        c - 'd'?
        c - 's' & c - 'k'?
        c - 'o' & c - 'c'?
        c - '\n'?
        A :
        printf(">> "), A :
        printf("%d\n", A), A :
        A * A :
        A - 1 :
        A + 1,
    A *= ~A && A - 256;
}

Tentei outra abordagem baseada na criação de uma tabela de pesquisa para decodificação de instruções, mas infelizmente isso acabou por mais tempo ( 169 ). Incluí-o, já que alguém pode apresentar um ajuste inteligente para reduzir o tamanho. (Deve ser executado sem argumentos)

#define X !--c?A

A,M[256];
main(c) {
  for(; !M['x']; c++) M["@osid\nckx"[c]]-=c%5+1;
  for (printf(">> "); c = ~M[getchar()]; A *= ~A && A - 256)
  A= X,printf("%d\n", A),A:X*A:X+1:X-1:A;
  main();
}
FireFly
fonte
3

C, 163

#define i(u,v);if(c==u+89|c==v+89)
a;main(c){printf(">>");while(c=getchar()-10){i(6,21)a++i(1,1)a--i(8,16)a*=a;i(0,12)printf("%d\n",a);a=a==-1|a==256?0:a;}main();}
Darren Stone
fonte
3

Python 3, 181 175 171 162

a=0
s=lambda x:"a=%d"%(x!=-1and x!=256and x)
while 1:
 for i in input(">>"):u,b,o=s(a+1),s(a*a),"print(a)";exec(dict(i=u,x=u,d=s(a-1),s=b,k=b,o=o,c=o).get(i,""))

Isso gera uma nova linha após o >>, mas o OP não disse que isso não era permitido. Não mais!

Graças a GlitchMr, miniteche golfer9338!

jazzpi
fonte
11
Você pode usar em lambdavez de defpara uma função que retorna imediatamente.
precisa
x in(-1,256)salva dois caracteres. Como alternativa, s=lambda x:"a=%d"%(x!=-1and x!=256and x)poderia salvar alguns.
Ry-
11
Você pode remover print(">>")e usar for i in input(">>"); input()permite especificar um prompt. Depois, não haverá nova linha depois >>e você salvará os caracteres.
golfer9338
Sua pontuação deve ser, eu acho, um caractere menor agora. Verifique novamente, mas recebo uma contagem de 161 em vez das 162 postadas: linhas de 3 + 40 + 8 + 107, mais 3 novas linhas. Verdade seja dita, estou com ciúmes, porque, de qualquer maneira, você é um pouco menor do que a minha resposta em C. Felicidades!
precisa
3

R, 161 , 148 , 138

a=0;repeat{x=readline(">> ");for(i in utf8ToInt(x)-99){a=a^((i==8|i==16)+1)+(i==6|i==21)-(i==1&a);a=a*(a!=256);if(i==0|i==12)cat(a,"\n")}}

Versão não destruída:

a = 0
repeat{
  x = readline(">> ")
  for(i in utf8ToInt(x) - 99) {
    a = a ^ ((i == 8 | i == 16) + 1) + (i == 6 | i == 21) - (i == 1 & a)
    a = a * (a != 256)
    if(i == 0 | i == 12) cat (a, "\n")
  }
}

Sessão de exemplo (no modo interativo):

>> xiskso
0
>> xiskisc
289
>> ddddo ddddo
285
281
>> ddddo ddddo
277
273
>> dddddddo
266
>> dddddddddo
257
>> do
0
>> do
0
>> io
1
>> 
Sven Hohenstein
fonte
3

Python 3, 141

Sei que estou muito atrasado, mas queria aproveitar a oportunidade para publicar uma versão mais curta do Python (e minha primeira tentativa do CodeGolf). :)

v=0
m=lambda y:(0,y)[-1!=y!=256]
i=x='+1'
d='-1'
s=k='*v'
c=o=');print(v'
while 1:
 for n in input('>>'):exec('v=m(v'+locals().get(n,'')+')')

A declaração impressa foi meio complicada para isso. Se o prompt precisar terminar com um espaço em branco, adicione um caractere à contagem. :)

Explicação

v é o acumulador.

mverifica se o valor fornecido é -1ou 256. Nesse caso, 0será retornado o valor caso contrário.

Nas linhas a seguir, as operações são atribuídas às variáveis ​​correspondentes (como algumas têm o mesmo significado (gostar ie x), isso é mais curto do que instanciar um novo dicionário). Esses são então usados ​​noexec abaixo.

while 1: é o loop principal

Agora a diversão começa. Como a solução do @jazzpi , ele itera sobre cada caractere da entrada. locals()é o dicionário de todas as variáveis ​​atuais (visíveis). Com .get(n,'')a chave correspondente será colocada na exec-string (uma string vazia, se a chave (= outra entrada) não foi encontrada). Isso será, quando executado, concatenado ve transmitido m. O valor de retorno será armazenado vnovamente.

Breve exemplo:

Be n = 'i'( n= input-char), saímos '+1'do localsbloco como ié a variável com valor '+1'.
A seqüência de caracteres para os execque se parece com isso: 'v=m(v+1)'.
Talvez agora seja mais fácil ver que, ao executar, ele chamará mcom o valor de v+1e armazenará sua saída vnovamente.

Repita isso até ficar entediado. :)

Dave J
fonte
Sei que estou MUITO atrasado para a festa, mas o lambda para m pode ser y*(-1!=y!=256)de -3 bytes
Restabelece Monica
apenas 5 anos :) obrigado pela contribuição embora. Estou com preguiça de corrigir a resposta não, mas vou ter isso em mente
Dave J
3

Python 2, 139

a=0
while 1:
 for c in raw_input(">> "):
  if c in'ix':a+=1
  if c=='d':a-=1
  if c in'sk':a*=a
  if c in'oc':print a
  if a in(-1,256):a=0

Isso é legal, mas também bastante direto. Aqui está uma versão mais longa e mais fria:

def i(a):
 while 1:
  c=yield
  if c in'ix':a+=1
  if c=='d':a-=1
  if c in'sk':a*=a
  if c in'oc':print a
  if a in(-1,256):a=0
 j=i(0);next(j)
while 1: 
 for c in raw_input(">> "):j.send(c)

Com 190 caracteres, talvez não seja a resposta mais competitiva aqui. Por outro lado, as corotinas são bem radicais e estou sempre procurando uma desculpa para usá-las (e compartilhá-las)

dingusman
fonte
3

TI-BASIC, 104 107 102 100 98

Para calculadoras da série TI-83 + / 84 +.

Nomeie isso prgmD; eventualmente, transborda a pilha chamando a si mesma. Substitua a recursão por a While 1, ao custo de dois bytes, para corrigir isso.

Input ">>",Str1
For(I,1,length(Str1
int(.5inString("?ixskd?oc",sub(Str1,I,1
If Ans=4
Disp Y
imag(i^Ans)+Y^int(e^(Ans=2     //decrements when Ans=3; increments when Ans=1
min(0,Ans(Ans≠256→Y
End
prgmD

Y é 0 por padrão, portanto, execute-o com uma calculadora limpa de memória recente ou armazene 0 a Y manualmente antes de executar isso.

Pena que as letras minúsculas (na sequência literal) são de dois bytes cada; caso contrário, isso seria mais curto que a resposta de Dom Hastings.

EDIT: Corrigido um erro de divisão por zero (0 ^ 0) ao custo de três bytes.

107 -> 102: usado truque de exponenciação imaginária para salvar quatro bytes (incluindo 1 dos parênteses e -1 do alongamento da cadeia de pesquisa) e usou Y em vez de X, que leva menos um byte para inicializar.

lirtosiast
fonte
2

Postscript 272

/cmd<</i{1 add}/x 1 index/d{1 sub}/s{dup mul}/k 1 index/o{dup =}/c 1 index>>def
0{(>> )print flush{/f(%lineedit)(r)file def}stopped{exit}if{f
1 string readstring not{exit}if cmd exch 2 copy known{get exec}{pop pop}ifelse
dup -1 eq 1 index 256 eq or{pop 0}if}loop pop}loop

Ungolfed:

/cmd <<  % define commands
/i { 1 add }
/x 1 index
/d { 1 sub }
/s { dup mul }
/k 1 index
/o { dup = }
/c 1 index
>> def
0        % accumulator on stack
{
    (>> )print flush   % print prompt
    { /f (%lineedit) (r) file def } stopped {exit} if  % read input line or quit
    {
        f 1 string readstring not {exit} if   % read 1-char string from line
        cmd exch 2 copy known { get exec }{ pop pop } ifelse   % execute command or don't
        dup -1 eq 1 index 256 eq or { pop 0 } if   % adjust accumulator if needed
    } loop
    pop
}loop
luser droog
fonte
2

C (224 212 caracteres)

Esta é provavelmente uma má escolha de idioma, mas tudo bem. Não é que linguagem como C possa fazer melhor do que alguma linguagem de programação dinâmica. No Clang, você precisará especificar um valor para return(isso não é necessário para o gcc).

#define s(x,y)case x:y;break;
main(){int c=10,a=0;for(;;){switch(c){s(-1,return)s('i':case'x',++a)s('d',--a)s('s':case'k',a*=a)s('c':case'o',printf("%d\n",a))s(10,printf(">> "))}a!=-1&a!=256||(a=0);c=getchar();}}
Konrad Borowski
fonte
Não seria mais curto remover define qe usar apenas printf?
Maçaneta
@DoorknobofSnow Na verdade não. qé usado 3 vezes, então define qsalva ~ 2 caracteres.
22413 Justin
2

Lua, 230 228

a=0repeat io.write(">> ")x=io.read()for i=1,#x do c=x:sub(i,i)if c=="i"or c=="x"then a=a+1 elseif c=="d"then a=a-1 elseif c=="s"or c=="k"then a=a*a elseif c=="o"or c=="c"then print(a)end if a==256or a==-1then a=0 end end until _

Não é o pior, não é o melhor.

NOTA: conforme relatado por @mniip 256or pode não funcionar no seu intérprete. Mais informações nos comentários.

(mais ou menos) Versão legível:

a=0
repeat
  io.write(">> ")
  x=io.read()
  for i=1,#x do
    c=x:sub(i,i)
    if c=="i"or c=="x"then
      a=a+1
    elseif c=="d"then
      a=a-1
    elseif c=="s"or c=="k"then
      a=a*a
    elseif c=="o"or c=="c"then
      print(a)
    end
    if a==256or a==-1then
      a=0
    end
  end  
until _

Saída:

>> xiskso
0
>> xiskisc
289
>> ddddo ddddo
285
281
>> ddddo ddddo
277
273
>> dddddddo
266
>> dddddddddo
257
>> do
0
>> do
0
>> io
1
>>

Edit: graças a @mniip para otimização de 2 caracteres: until nil->until _

Egor305
fonte
repeat until x(x é nulo como não definido) é 2 caracteres mais curto e while 1 do endtem exatamente o mesmo comprimento, além da versão lua? 256oré sintaxe inválida no meu intérprete
mniip 26/12/2013
@ mniip Obrigado pela dica sobre repeat until x. Estou usando o último binário do Windows a partir daqui . Como você pode ver, a=a+1 elseiftem espaço. Isso eocorre porque o dígito hexadecimal, enquanto oin 256or, não é, então meu intérprete toma orcomo outra instrução / block / howYouCallIt.
Egor305
sim 256or, além disso , também 0repeate 1then; Estou usando lua oficial do lua.org, seu código não é compilado em 5.1, 5.2 ou 5.3
mniip
2

Haskell , 186 178 bytes

Isso precisa ser executado com runhaskell(ou dentro ghci) uma vez que ambos definir o BufferModeque NoBufferingpor padrão que cofres bastante bytes:

infix 4#
-1#x=0#x
256#x=0#x
r#x:y=case x of 'i'->r+1#y;'x'->r+1#y;'d'->r-1#y;'s'->r^2#y;'k'->r^2#y;'o'->print r>>r#y;'c'->r#'o':y;_->r#y
r#_=putStr">> ">>getLine>>=(r#)
main=0#""

Experimente online!

Explicação

Isto define um novo operador state # source(a declaração fixidez nos permite cair parênteses quando usá-lo em conjunto com outros operadores (+), (-), (^), (:)e (>>)):

  • as duas primeiras linhas "consertam" os estados -1e256
  • ele combina com o primeiro caractere e age sobre ele
  • quando ficar sem caracteres ( r#_), ele lê novos e começa novamente, mantendo o estado antigo

Para iniciar o processo, inicializamos o estado com 0 e lemos uma nova linha de origem, ie. comece com uma fonte vazia:

main=0#""
ბიმო
fonte
1

Lote do Windows, 204 256

@echo off
set a=0
:a
set /p i=^>^> 
if %i%==i set /a a=%a%+1
if %i%==x set /a a=%a%+1
if %i%==d set /a a=%a%-1
if %i%==s set /a a=%a%*%a%
if %i%==k set /a a=%a%*%a%
if %i%==o echo %a%
if %i%==c echo %a%
if %a%==256 set a=0
if %a%==-1 set a=0
set i=n
goto a

Ignora com êxito outros comandos. Realmente ficou inchado sem teror que trabalhar com ...

Editar:

Fixo:

  • Não mais ecoando todos os comandos
  • Realmente fiz matemática com / a
  • Redefinir em -1
  • Redefinir entrada após cada ciclo

Isso custou 52 caracteres.

Não corrigiu:

  • O quadrado 0 grava "0 * 0" em a.
  • Introduzir espaço (ou não inserir nada, quando você o abriu) trava o script.
  • Você PRECISA inserir um caracter por vez.
Timtech
fonte
2
Este simplesmente não funciona (Windows 7). Não pretendo ser um idiota, mas você testou isso?
marinus
@ marinus Foi consertado.
Timtech
1

Script de comando do Windows - 154

Abusin características desconhecidas ao máximo.

@echo off
set i=1
set x=1
set d=-1
set/as=[*[-[
set/ak=[*[-[
set.=0
set/p.=^>^> 
set/a[=[+%.%
e%.:o=c%h%.:c=o% %[% 2>nul
set[=%[:-1=%
if;%[%==256 set[=
%0
Robert Sørlie
fonte
1

> <> , 258 bytes

Fiz outra resposta> <> desde que não pude testar as fases e ele usou comandos pré-empilhados em vez de emular um shell de qualquer maneira.

0v
"<vooo">> 
!~>i:0)?v~ >
 ^?=a:  /  ^!?="c"v?="o":v?="s":v?="k":v?="d":v?="x":v?="i":
   voan:<        ~<  v*:~<      <  v-1~<  v+1~<      <
   <                 <             <      <vv?=-10:v?=*:+1f:
  v                                        <>      >~0

Certamente, isso pode ser aproveitado, mas não tenho certeza se terei a bravura de insanidade necessária !

Testei-o com o intérprete oficial em execução no python 3.5 no cygwin no windows 7 e pude reproduzir o teste:

$ python fish.py deadfish.fish
>> xiskso
0
>> xiskisc
289
>> ddddo ddddo
285
281
>> ddddo ddddo
277
273
>> dddddddo
266
>> dddddddddo
257
>> do
0
>> do
0
>> io
1
>> (pressed ctrl-Z)Stopped

Caso você não possa executá-lo em sua máquina (a entrada parece complicada) ou apenas queira testá-lo sem nenhum outro software, você pode usar a seguinte versão no interpretador on - line .

0v
 <vooo">> "<
  >i:0)?v~
      o:/  ^!?="c"v?="o":v?="s":v?="k":v?="d":v?="x":v?="i":
 ^oanoa:<        ~<  v*:~<      <  v-1~<  v+1~<      <
   <                 <             <      <vv?=-10:v?=*:+1f:
  v                                        <>      >~0

Obviamente, desconsidera \ n e EOF, pois você não pode inseri-los no interpretador on-line, mas se comportará como se a tecla enter tivesse sido pressionada após cada comando de saída.

Aaron
fonte
1

C (gcc) , 139 bytes

Compilar com -Dk="_nZZiaeY"(incluído na contagem de bytes). -2 bytes se o prompt >>\nfor permitido.

x;f(c){for(printf(">>");c=getchar()-10;x+=c--?c--?c--?c||printf("%i\n",x),0:x*x-x:-1:1,x*=~x&&x^256)c=strchr(k,c)-k>>1;f();}

Experimente online!

Degolf

/** Preprocessor **/
-Dk="_nZZiaeY" // This is a lookup string; it corresponds to "ixddskoc",
               // with 10 deducted from each character. Upon compilation, 
               // all occurences of the string literal are replaced with a 
               // pointer to its location in memory.

/** Source **/
x;f(c){ // x: 32-bit accumulator, c: local variable for read character
    for(printf(">>"); // Start for-loop and print prompt.
            c=getchar()-10; // Read a character from STDIN.
                            // Loop breaks if it is '\n'.

            // The below happens at the end of each iteration.
            x+=c--?c--?c--? 
               // Find the correct operation by testing c and post-
               // decrementing with multiple ternary-ifs. If c is 0, 
               // operation was found, add the else-value to the 
               // accumulator x.
               //     If the character is invalid, the value of c is
               // very large, and will not reach 0 with 3 decrements.

               c||printf("%i\n",x),0 
               // If c-3 is 0, print accumulator, else do nothing.
               // Returns 0 regardless of what happens. (No change to x)
               :x*x-x 
               // Square. Results in x=x+x*x-x, and is shorter than (x*=x)
               :-1:1, 
               // Decrement, Increment.
               x*=~x&&x^256 
               // Because -1==0xffffffff, ~x==0 when x==-1. Likewise,
               // x^256==0 only when x==256. The logical-AND coerces the result
               // to boolean 1 (no match) or 0 (match). Multiplication resets
               // the accumulator as appropriate.
           )
        // This is the actual body of the for-loop
        c=strchr(k,c)-k>>1; 
           // Finds the index of the read character in the lookup string,
           // then "divides" it by two.
           // Because strchr() returns NULL (0) when character is not found,
           // deducting k from it results in a very negative number.
           // The right-shift results in division by 2 for positive numbers, 
           // while the negative numbers become very large positive numbers
           // (c >= 0x70000000) because of the 2's complement representation.
    // Finally, recurse until forceful termination.
    f();
}

fonte
1

Barril , 68B

0{'::"ÿ1+=$0<+['_0"] \>\>\
,,,,?:o=[':."]:i=['1+"]:d=['1-"]:s=[':*"
UMA
fonte
0

Haskell, 230

import System.IO
i""n=[]
i(a:b)n 
 |a=='o'||a=='c'=[n]++i b n
 |True=i b$v a n
v a n=w(case a of 'i'->n+1;'x'->n+1;'d'->n-1;'s'->n^2;'k'->n^2)
w(-1)=0
w 256=0
w n=n
main=do;putStr ">> ";hFlush stdout;s <- getLine;print$i s 0;main

Se ao menos eu conseguisse me livrar daquela hFlush stdoutligação traquina ! Sem ele, o prompt não é exibido até que uma ooperação seja executada. Algum conselho?

danmcardle
fonte
Você pode se livrar dele hFlushusando em runhaskellvez de compilar (veja minha resposta ), mas, quanto a esta solução, ela não é válida e não gera erros.
ბიმო
0

PHP + HTML 345

<form><?php $i=0;$o='';if(isset($_GET[i])){$i=$_GET[a];foreach(@str_split($_GET[i]) as $j=>$v){$v==i||$v==x?$i++:($v==d?$i--:($v==k||$v==s?$i*=$i:($v==o||$v==c?$o.=$i."\n":'')));($i==256||$i==-1)&&$i=0;}$_GET[p].='>> '.$_GET[i]."\n".$o;echo"<textarea locked name=p>$_GET[p]</textarea><input type=hidden name=a value=$i><br>";}?>>> <input name=i>

a saída é um pouco superficial (o histórico / sessão é mostrado em uma área de texto e, com o relatório de erros ativado, muitos avisos são impressos), mas tudo funciona

Einacio
fonte
0

239

v
\r0&
v                  <
\&::&01-=$f1+:*=+?v
v             &0~&<
\:"i"=?v
       >~&1+&      ^
\:"d"=?v
       >~&1-&      ^
\:"s"=?v
       >~&:*&      ^
\:"o"=?v
       >~&:o&      ^
\:"h"=?v
       >~;        (^)
>~                 ^

A pilha inicial é a entrada. Você pode experimentá-lo online aqui .

Estágio
fonte
0

Golf-Basic 84, 88 caracteres

:0_A:0_O:1_I:2_D:3_S:O_C:I_X:S_Kl`1i`N@A=256:0_A@N=0d`A@N=1:A+1_A@N=2:A-1_A@N=3:A^2_Ag`1

Solicita um comando de cada vez, como em pelo menos 3 outras soluções. Aqui está um teste para xiskisc:

?X
?I
?S
?K
?I
?S
?C
             289

Além disso, xisksogera 0, como deveria.

Timtech
fonte
Quais outras soluções solicitam um comando de cada vez?
Ry-
11
Eu escrevi o Haskell, e não, não. Nem o Perl, então eu realmente não tenho certeza do que você está falando.
Ry-
11
Isso não segue as regras de E / S.
Marinus
11
Ainda não segue as regras e usa letras maiúsculas em vez de minúsculas.
lirtosiast
11
Se você conhece o TI-BASIC, ele suporta apenas entradas em maiúsculas.
Timtech
0

JavaScript (Node.js), 204 bytes

process.openStdin(f=a=>process.stdout.write((i=0,""+a).split` `.map(x=>([...x.slice(0,-1)].map(d=>({i:x=e=>i++,d:e=>i--,s:k=e=>i*=i,o:c=e=>e,x,k,c})[d](i=-1||i==256?i=0:0)),i))+"\n>> "),f``).on("data",f)

Provavelmente isso pode ser jogado no golfe. O Node.js novamente prova que é uma verbosidade disfarçada estranha mais uma vez. Código explicado:

process.openStdin( // This function has to be called to take input, but doesn't have arguments
  f=a=> // Define a function f. This is the deadfish interpreter. It takes an argument `a` which is a Buffer
  process.stdout.write( // Same as console.log, but doesn't output trailing newline
    (i = 0, "" + a) // Take advantage of comma operator to (A) define the accumulator i, and casts a (which is a Buffer) to a String
      .split` ` // Split the string a at spaces, making it an array
      .map(     // Map through each element of the array
        x=>     // Map function, takes argument x, the value in the array (string)
          ([...x.slice(0,-1)] // Remove the last character (newline) and than use the spread operator to divide the string into an array of it's chars
            .map(d=> // Map function, you know how this works
              ({ // Here I define the various deadfish commands
                i: x = e => i++,
                d: e => i--,
                s: k = e => i*=i,
                o: c = e => e,
                // Take advantage of ES6 object notation. Equivilent to {"x": x, "k": k, "c", c}
                x,
                k,
                c
              })
              [d] // Get the command to execute. If this is passed something which isn't valid, a giant error will appear
              (
                i==-1 || i==256 ? i = 0 : 0 // Take advantage of the fact that none of the command functions take arguments to handle the strange "overflow"
              )
            ),
          i)
      ) +
  "\n>> "), // Display the prompt again, as well as a newline
  f`` // Initalize the prompt by passing an empty script
)
.on("data",f) // Bind the f function to newline on STDIN
MayorMonty
fonte
0

C #, 311 bytes

using System;class p{static void Main(){int a=0;int s(int b)=>b==-1||b==256?0:b;while(true){Console.Write(">>");var c=Console.ReadLine();for(int i=0;i<c.Length;i++){switch(c[i]){case'i':case'x':a=s(a+1);break;case'd':a=s(a-1);break;case's':case'k':a=s(a*a);break;case'o':case'c':Console.WriteLine(a);break;}}}}}

seria de 283 bytes se usings e declaração de classe, etc, pudessem ser omitidos fornecendo apenas uma definição de função

Robin B
fonte