Scrivi un interprete Deadfish interattivo


30

Deadfish è un "linguaggio di programmazione" scherzoso con quattro comandi. Poiché la pagina Esolang è un po 'contraddittoria e gli interpreti in quella pagina non funzionano tutti esattamente allo stesso modo, è necessario implementare la seguente variante:


specificazione

  1. C'è un accumulatore che ha una dimensione di almeno 16 bit, più è permesso ma meno non lo è. I numeri negativi non devono essere supportati. L'accumulatore è 0all'avvio del programma.
  2. Esistono i seguenti due set di quattro comandi e il programma deve supportare entrambi contemporaneamente.
      Pesce morto standard │ Variante XKCD │ Significato
      ─────────────────────┼──────────────────┼───────── ───────────────────────────
            i │ x │ Accumulatore di incremento
            d │ d │ Accumulatore di decremento
            s │ k │ Square (acc = acc * acc)
            o │ c │ Accumulatore di uscita, come numero
    
  3. Se, dopo aver eseguito un comando, l'accumulatore è uno -1o 256, l'accumulatore deve essere ripristinato a zero. Si noti che questo non è normale. Se, per esempio, l'accumulatore è 20e il scomando viene eseguito, l'accumulatore dovrebbe essere in 400seguito. Allo stesso modo, se l'accumulatore è 257e il dcomando viene eseguito, l'accumulatore dovrebbe diventare 0.
  4. Qualsiasi input che non è uno di questi comandi deve essere ignorato.

Programmi di test

  • xiskso dovrebbe produrre 0
  • xiskisc dovrebbe produrre 289

I / O

Il vostro programma dovrebbe visualizzare un prompt: >>. Il prompt deve essere all'inizio di una nuova riga. Dovrebbe quindi leggere una riga di input dell'utente ed eseguire i comandi dati da sinistra a destra. Quando si generano numeri, i numeri devono essere separati. Cioè, 12 34va bene, 12,34va bene,

12
34 

va bene, ma 1234non lo è.

Il tuo programma dovrebbe continuare a farlo in un ciclo, almeno fino a quando non EOFviene raggiunto.

Sessione di esempio:

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

A causa della richiesta di input, non riesco a usare GolfScript :-(
ProgramFOX il

@ProgramFOX: puoi usare l'input ruby ​​giusto?
Marin il

Secondo il tutorial di GolfScript, non è possibile richiedere input in GolfScript, tutti gli input provengono da STDIN.
Programma FOX il

@ProgramFOX: avrei pensato che qualcosa del genere #{STDIN.gets}avrebbe funzionato, ma in effetti non lo è.
Marin il

È consentito invece inserire input con lettere maiuscole?
lirtosiast,

Risposte:


6

K, 77 byte

  {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

Nota che questo è K4 . Una soluzione K6 è leggermente più lunga perché i verbi IO sono più lunghi, anche se tutto il resto è migliore:

{""0:">>";0{x*^-1 256?x:y@x}/("xkcdiso"!7#(1+;{x*x};{""0:,$x;x};-1+))@0:"";o`}`
  • ""0:stampa e restituisce il suo argomento. Nota in K4 applichiamo semplicemente 1 .
  • 0 f/ args dimostra ridurre con un valore iniziale, cioè f[f[0;first arg];second arg]…
  • {x*2=-1 256?x…classifica x in 0 (per -1), 1 (per 256) e 2 per tutti gli altri valori. 2=significa che otteniamo 1valori non classificati e 0, in caso contrario, moltiplicare per xè più breve di un condizionale. In K6 possiamo fare un po 'meglio perché {x*^-1 256?x:y@x}si basa sul fatto che -1 256?xrestituisce 0N(null) e ^rileva null.
  • Il "parser" è la mappa "xkcdiso"anziché l'ordine suggerito perché 7#avvolgerà i quattro argomenti, ovvero i 7#"abcd"ritorni "abcdabc"che mantengono la nostra tabella più piccola
  • La mappa si traduce "x"e "i"alla proiezione 1+che è equivalente alla funzione {1+x}ma più breve.
  • La mappa si traduce "d"in una proiezione -1+equivalente alla funzione {-1+x}ma più breve.
  • La mappa si traduce "k"e "s"alla funzione{x*x}
  • La mappa si traduce "c"e "o"nella funzione di output {-1@$x;x}che di nuovo in K6 è leggermente più lunga: {""0:,$x;x}ma entrambi stampano il suo output seguito da una nuova riga e quindi restituiscono l'argomento.
  • .zs è auto-ricorsione. In K6 possiamo semplicemente dire o`quale è più breve.

8

Perl 5 , 90 byte

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

Provalo online!

Grazie a @xfix per il suo aiuto su questo in precedenza! 4 byte salvati grazie a @Xcali !


1
Il programma stampa 1quando l'accumulatore trabocca. Inoltre, puoi accorciare il tuo programma di cinque caratteri, cambiando $ain $?(che è inizializzato in 0e non cambierà fino a quando non eseguirai un programma esterno da Perl).
Konrad Borowski il

Ahhhh, stavo cercando una variabile che potevo usare, perfetto, grazie! Per quanto riguarda lo straripamento, non me ne sono accorto dato che succede solo se si esegue isssocome un comando, non se si esegue ciascuno separatamente ... Daremo un'occhiata più avanti e sicuramente lo userò $?. Grazie!
Dom Hastings,

Quindi penso di aver lasciato una versione precedente nella sezione di codice in alto con ''invece di ""così quando usato con perl -e '...'la mappa finirebbe con il risultato di s///. Grazie ancora!
Dom Hastings,

OK, sei il più corto.
Marin

1
Non è più la risposta più breve.
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){...} - imposta l'accumulatore su 0 e esegui il ciclo per sempre
  • read-host '>>' - ottenere l'input dell'utente con prompt >>
  • [char[]](...) - converte l'input dell'utente in una matrice di caratteri
  • |%{...} - esegui ciò che c'è dentro {}per ogni personaggio
  • switch -r($_) - interruttore regex per ogni personaggio
  • "i|x"{$x++} - abbina io x- aumenta l'accumulatore
  • "d"{$x-=!!$x} - match d- diminuisce $xdi !!$x, che sarà 0se lo $xè 0, e 1altrimenti. Questo assicura che l'accumulatore non raggiunga mai -1.
  • "s|k"{$x*=$x} - partita so k- piazza
  • "o|c"{$x} - corrisponde oo c- genera l'accumulatore
  • $x*=$x-ne256- moltiplicare l'accumulatore per 0se è 256o per 1altrimenti

Esempio di output

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

Immagino che l'implementazione read-hostsia specifica dell'host, quindi questo host Powershell (ConsoleHost) si aggiunge :al prompt specificato.


Bello! Adoro il decremento di !!$x, peccato che non riesca a utilizzarlo ...
Dom Hastings il

Ehi Danko, potresti pubblicare dei risultati del test, per favore? Non credo di poter provare Power Shell su non Windows ... (per favore, correggimi se sbaglio!)
Dom Hastings,

Ho aggiunto alcuni risultati del test alla risposta.
Danko Durbić, il

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]

Versione più carina:

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]

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

Probabilmente potresti salvare alcuni personaggi cambiando ee vin operatori. Ho anche provato a riscrivere ve in gmodo che il parametro xrimanga in IO e così printvia venga sollevato. Non sono riuscito a farlo funzionare, ma penso che potrebbe essere un buon posto dove andare per qualcuno che conosce il loro haskell.
shiona,

@shiona: Sì, la cosa importante IOè che le cose vengono stampate troppo spesso (è per questo che l'ho usato al r nposto di x) o non abbastanza perché il valore non viene mai richiesto ... Quindi, come cambierei ee vin operatori?
Ry,

Ho avuto gli stessi problemi con la stampa. Cosa può fare un operatore (usando e come esempio) 'i'%x=x+1;'d'%x=x-1... E chiamalo in v do n<-x;r$w$o%n. Il motivo per cui gli operatori risparmiano spazio è che non richiedono spazi attorno a loro.
shiona,

@shiona: Oh! Buona chiamata, grazie!
Ry,

Nessun problema. Ho pensato per la prima volta di dare una risposta, ma dato che non riuscivo a far funzionare le mie grandi idee, ho pensato che sarebbe stato scortese pubblicare esattamente lo stesso codice con una notazione diversa per le stesse funzioni.
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;'}}

Sessione di esempio (uguale alla tua):

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
>>

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
>>

La mia versione è più corta. Ho compresso la mappa, invocato ? classificare per "avvolgere" i valori, usare la ricorsione invece di while e un interprete funzionale invece di modificare.
geocar,

4

Ada

Ecco un'implementazione di Ada per i pochi interessati a questa lingua. Mi ci è voluto un po 'di tempo per utilizzare alcune delle migliori pratiche di Ada (come l'uso di Indefinite_Holders anziché l'accesso) e anche per comprendere appieno come deve funzionare Deadfish.

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 l'output:

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

Se alcune persone sperimentate in Ada potessero darmi alcuni suggerimenti per l'ottimizzazione, sarei grato.


1
Benvenuti in PPCG! L'obiettivo del code-golf è quello di creare il codice più breve possibile e dovresti includere la dimensione del tuo programma nell'intestazione (1396 byte qui)
TuxCrafting

4

C, 159 caratteri

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;
}

Ho provato un altro approccio basato sull'impostazione di una tabella di ricerca per la decodifica delle istruzioni, ma sfortunatamente quello è finito più a lungo ( 169 ). L'ho incluso dal momento che qualcuno potrebbe inventare una modifica intelligente per ridurre le dimensioni. (Deve essere eseguito senza argomenti)

#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();
}

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();}

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,""))

Questo genera una nuova riga dopo il >>, ma l'OP non ha detto che non era permesso. Non più!

Grazie a GlitchMr, miniteche golfer9338!


1
È possibile utilizzare lambdaanziché defper una funzione che restituisce immediatamente.
Konrad Borowski il

x in(-1,256)salva due personaggi. In alternativa, s=lambda x:"a=%d"%(x!=-1and x!=256and x)potrebbe salvarne un po '.
Ry,

1
È possibile rimuovere print(">>")e utilizzare for i in input(">>")invece; input()consente di specificare un prompt. Quindi, non ci sarà più una nuova riga >>e salverai i personaggi.
golfista 933

Il tuo punteggio dovrebbe essere, credo, un carattere più breve in questo momento. Per favore, ricontrolla, ma ottengo un conteggio di 161 anziché i 162: righe di 3 + 40 + 8 + 107, più 3 nuove righe. A dire il vero, sono geloso, perché in entrambi i casi, sei pochi caratteri più corto della mia risposta C. Saluti!
Darren Stone,

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")}}

Versione non golfata:

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")
  }
}

Sessione di esempio (in modalità interattiva):

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

3

Python 3, 141

So di essere in ritardo, ma volevo cogliere l'occasione per pubblicare una versione più breve di Python (e il mio primo tentativo di 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,'')+')')

La dichiarazione stampata è stata un po 'complicata per questo. Se il prompt deve terminare con uno spazio bianco, aggiungere un carattere al conteggio. :)

Spiegazione

v è l'accumulatore.

mcontrolla se il valore dato è -1o 256. Se è così,0 verrà restituito, il valore altrimenti.

Nelle righe seguenti le operazioni sono assegnate alle variabili corrispondenti (poiché alcune hanno lo stesso significato (come ie x) ciò è più breve dell'istanza di un nuovo dizionario). Quelli vengono quindi utilizzati inexec seguito.

while 1: è il ciclo principale

Ora inizia il divertimento. Come la soluzione di @jazzpi , scorre su ogni carattere dell'input. locals()è il dizionario di tutte le variabili correnti (visibili). Con .get(n,'')la chiave corrispondente verrà inserito nella stringa exec (una stringa vuota, se la chiave (= altro input) non è stata trovata). Questo sarà, una volta eseguito, concatenato ve passato m. Il valore restituito verrà nuovamente memorizzato v.

Breve esempio:

Be n = 'i'( n= input-char), usciamo '+1'dal localsblocco come iè la variabile con valore '+1'.
La stringa per il execrispetto aspetto: 'v=m(v+1)'.
Forse ora è più facile vedere che, durante l'esecuzione, chiamerà mcon il valore di v+1e memorizzerà di vnuovo l'output .

Ripeti finché non ti annoi. :)


Mi rendo conto di essere MOLTO in ritardo alla festa, ma la lambda per m può essere y*(-1!=y!=256)di -3 byte
Ripristina Monica

solo 5 anni :) grazie per l'input però. Sono troppo pigro per sistemare la risposta, ma la terrò a 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

Questo è pulito, ma anche piuttosto semplice. Ecco una versione più lunga e più interessante:

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)

Con un peso di 190 caratteri, non è forse la risposta più competitiva qui. D'altra parte, le coroutine sono piuttosto belle e cerco sempre una scusa per usarle (e condividerle)


3

TI-BASIC, 104 107 102 100 98

Per calcolatori serie TI-83 + / 84 +.

Nomina questo prgmD; alla fine trabocca lo stack chiamando se stesso. Sostituire la ricorsione con a While 1, al costo di due byte, per risolvere il problema.

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 per impostazione predefinita, quindi eseguirlo con una calcolatrice appena cancellata dalla memoria o memorizzare manualmente da 0 a Y prima di eseguirlo.

Peccato che le lettere minuscole (nei letterali stringa) siano due byte ciascuna; altrimenti ciò sarebbe più breve della risposta di Dom Hastings.

EDIT: risolto un errore di divisione per zero (0 ^ 0) al costo di tre byte.

107 -> 102: usato un trucco di esponenziale immaginario per salvare quattro byte (di cui 1 tra parentesi e -1 dall'allungamento della stringa di ricerca) e usato Y invece di X, che richiede un byte in meno per inizializzare.


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

2

C (224 212 caratteri)

Questa è probabilmente una cattiva scelta della lingua, ma vabbè. Non è che un linguaggio come C possa fare di meglio di un linguaggio di programmazione dinamico. Su Clang, dovrai specificare un valore per return(questo non è necessario per 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();}}

Non sarebbe più breve rimuovere define qe usare solo printf?
Maniglia della porta

@DoorknobofSnow In realtà no. qviene usato 3 volte, quindi define qrisparmia ~ 2 caratteri.
Justin il

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 _

Non il peggio, non il migliore.

NOTA: come riportato da @mniip 256or potrebbe non funzionare nell'interprete. Maggiori informazioni nei commenti.

(più o meno) Versione leggibile:

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 _

Produzione:

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

Modifica: grazie a @mniip per l'ottimizzazione di 2 caratteri: until nil->until _


repeat until x(x è nullo in quanto non definito) è più corto di 2 caratteri ed while 1 do endè esattamente della stessa lunghezza, a parte quello che versione lua è? 256orè una sintassi non valida nel mio interprete
mniip il

@mniip Grazie per il suggerimento repeat until x. Sto usando l'ultimo binario di Windows da qui . Come puoi vedere a=a+1 elseifavere spazio. Questo perché eè una cifra esadecimale, mentre oin 256ornon lo è, quindi il mio interprete prende orun'altra istruzione / blocco / howYouCallIt.
Egor305,

sì praticamente oltre 256or, anche 0repeate 1then; Sto usando lua ufficiale da lua.org, il tuo codice non viene compilato in 5.1, 5.2 o 5.3
mniip

2

Haskell , 186 178 byte

Questo deve essere eseguito con runhaskell(o dentro ghci) poiché entrambi impostare la BufferModea NoBufferingdi default che cassaforte un bel po 'di byte:

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#""

Provalo online!

Spiegazione

Ciò definisce un nuovo operatore state # source(dichiarazione fixity ci permette di cadere parentesi quando viene utilizzato in combinazione con altri operatori (+), (-), (^), (:)e (>>)):

  • le prime due righe "riparano" gli stati -1e256
  • quindi abbina il primo personaggio e agisce su di esso
  • una volta esauriti i caratteri ( r#_), ne legge di nuovi e ricomincia da capo mantenendo il vecchio stato

Per iniziare il processo inizializziamo lo stato con 0e leggiamo una nuova linea sorgente, ad es. inizia con una fonte vuota:

main=0#""

1

Lotto di 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 correttamente altri comandi. Davvero gonfiato senza dover orlavorare con ...

Modificare:

Fisso:

  • Niente più eco di tutti i comandi
  • Realizzato in realtà fare matematica con / a
  • Ripristina su -1
  • Ripristina input dopo ogni ciclo

Questo costa 52 caratteri.

Non risolto:

  • La quadratura 0 scrive "0 * 0" in a.
  • L'inserimento dello spazio (o l'inserimento di nulla, quando lo hai appena aperto) provoca l'arresto anomalo dello script.
  • È NECESSARIO inserire un carattere alla volta.

2
Questo semplicemente non funziona affatto (Windows 7). Non intendo essere uno stronzo, ma hai provato questo?
Marin il

@marinus È stato risolto.
Timtech,

1

Script di comando di Windows - 154

Abusin caratteristiche sconosciute al massimo.

@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

1

> <> , 258 byte

Ho fatto un'altra risposta> <> poiché non ho potuto testare la fase e ha usato comandi pre-impilati piuttosto che emulare comunque una shell.

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

Si può certamente giocare a golf, ma non sono sicuro che avrò il coraggio di follia necessario !

L'ho provato con l'interprete ufficiale in esecuzione su Python 3.5 in Cygwin in Windows 7 e ho potuto riprodurre l'esecuzione del test:

$ 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

Nel caso in cui non sia possibile eseguirlo sul proprio computer (l'input sembra essere complicato) o si desidera semplicemente provarlo senza altri software, è possibile utilizzare la seguente versione sull'interprete online .

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

Ovviamente ignora \ n ed EOF poiché non è possibile inserirli nell'interprete online, ma si comporterà come se fosse stato premuto enter dopo ogni comando di output.


1

C (gcc) , 139 byte

Compilare con -Dk="_nZZiaeY"(incluso nel conteggio dei byte). -2 byte se il prompt >>\nè consentito.

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();}

Provalo 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();
}

1

Keg , 68B

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

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 solo potessi liberarmi di quella fastidiosa hFlush stdoutchiamata! Senza di essa, il prompt non viene visualizzato fino a quando non oviene eseguita un'operazione. Qualche consiglio?


Puoi sbarazzartene hFlushusando runhaskellinvece di compilare (vedi la mia risposta ), ma per quanto riguarda questa soluzione non è valida ed errori.
ბიმო

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>

l'output è un po 'impreciso (la cronologia / la sessione viene visualizzata in un'area di testo e con la segnalazione degli errori abilitata vengono stampati molti avvisi) ma tutto funziona


0

> <>, 239

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

Lo stack iniziale è l'input. Puoi provarlo online qui .


0

Golf-Basic 84, 88 caratteri

: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

Richiede un comando alla volta, come in almeno altre 3 soluzioni. Ecco una prova per xiskisc:

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

Inoltre, xisksogenera 0, come dovrebbe.


Quali altre soluzioni richiedono un comando alla volta?
Ry,

1
Ho scritto quello di Haskell e no, non lo è. Né il Perl, quindi non sono proprio sicuro di cosa tu stia parlando.
Ry,

1
Questo non segue le regole I / O.
Marin il

1
Non segue ancora le regole e utilizza lettere maiuscole anziché minuscole.
Lirtosiast

1
Se conosci TI-BASIC, supporta solo input maiuscoli.
Timtech,

0

JavaScript (Node.js), 204 byte

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)

Questo può probabilmente essere giocato a golf. Node.js dimostra ancora una volta la sua strana verbosità mascherata. Codice spiegato:

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

0

C #, 311 byte

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;}}}}}

sarebbe 283 byte se gli usi, la dichiarazione di classe ecc. potrebbero essere utilizzati semplicemente fornendo una definizione di funzione

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.