Schreiben Sie einen interaktiven Deadfish-Interpreter

30

Deadfish ist eine Scherz- "Programmiersprache" mit vier Befehlen. Da die Esolang-Seite etwas widersprüchlich ist und die Interpreten auf dieser Seite nicht alle genau gleich funktionieren, sollten Sie die folgende Variante implementieren:


Spezifikation

  1. Es gibt einen Akkumulator mit einer Größe von mindestens 16 Bit, mehr ist zulässig, weniger nicht. Negative Zahlen müssen nicht unterstützt werden. Der Akku ist, 0wenn das Programm startet.
  2. Es gibt die folgenden zwei Sätze von vier Befehlen, und Ihr Programm muss beide gleichzeitig unterstützen.
      Standard Deadfish (XKCD-Variante) Bedeutung
      ─────────────────────┼──────────────────┼───────── ───────────────────────────
            i │ x │ Inkrementspeicher
            d │ d │ Dekrementspeicher
            s │ k │ Quadrat (acc = acc * acc)
            o │ c │ Akkumulator als Zahl ausgeben
    
  3. Wenn der Akku nach Ausführung eines Befehls entweder -1oder ist 256, muss der Akku auf Null zurückgesetzt werden. Beachten Sie, dass dies kein normaler Umlauf ist. Wenn zum Beispiel der Akku ist 20und der sBefehl ausgeführt wird, sollte der Akku 400danach sein. Wenn der Akku ist 257und der dBefehl ausgeführt wird , sollte der Akku in ähnlicher Weise werden 0.
  4. Alle Eingaben, die nicht zu diesen Befehlen gehören, sollten ignoriert werden.

Testprogramme

  • xiskso sollte ausgeben 0
  • xiskisc sollte ausgeben 289

I / O

Ihr Programm sollte eine Eingabeaufforderung angezeigt: >>. Die Eingabeaufforderung muss am Anfang einer neuen Zeile stehen. Anschließend sollte eine Zeile mit Benutzereingaben gelesen und die angegebenen Befehle von links nach rechts ausgeführt werden. Bei der Ausgabe von Zahlen müssen die Zahlen getrennt werden. Das heißt, 12 34ist in Ordnung, 12,34ist in Ordnung,

12
34 

ist OK, ist es aber 1234nicht.

Ihr Programm sollte dies in einer Schleife tun, zumindest bis EOFes erreicht ist.

Beispielsitzung:

>> xiskso
0
>> xiskisc
289
>> ddddo ddddo
285
281
>> ddddo ddddo
277
273
>> dddddddo
266
>> dddddddddo
257
>> do
0
>> do
0
>> io
1
>> 
Marinus
quelle
Aufgrund der Eingabeaufforderung kann ich GolfScript nicht verwenden :-(
ProgramFOX
@ProgramFOX: Du kannst die Rubineingabe verwenden, oder?
Marinus
Gemäß dem GolfScript-Tutorial können Sie in GolfScript keine Eingaben vornehmen, da alle Eingaben von STDIN stammen.
ProgramFOX
@ProgramFOX: Ich hätte gedacht, dass so etwas #{STDIN.gets}funktionieren würde, aber in der Tat funktioniert es nicht.
Marinus
Dürfen wir stattdessen Großbuchstaben eingeben?
Lirtosiast

Antworten:

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

Beachten Sie, dass dies K4 ist . Eine K6- Lösung ist etwas länger, weil die IO-Verben länger sind, auch wenn alles andere besser ist:

{""0:">>";0{x*^-1 256?x:y@x}/("xkcdiso"!7#(1+;{x*x};{""0:,$x;x};-1+))@0:"";o`}`
  • ""0:gibt das Argument aus und gibt es zurück. Beachten Sie in K4, dass wir uns einfach auf 1 beziehen .
  • 0 f/ args zeigt reduzieren mit einem Anfangswert, dh f[f[0;first arg];second arg]…
  • {x*2=-1 256?x…klassifiziert x in 0 (für -1), 1 (für 256) und 2 für alle anderen Werte. 2=Das heißt, wir erhalten 1für nicht klassifizierte Werte und 0ansonsten ist das Multiplizieren mit xkürzer als eine Bedingung. In K6 können wir ein wenig besser, weil {x*^-1 256?x:y@x}auf der Tatsache beruht , dass -1 256?xRenditen 0N(null) und ^erkennt Nullen.
  • Der "Parser" ist die Map "xkcdiso"anstelle der vorgeschlagenen Reihenfolge, da 7#die vier Argumente, dh die 7#"abcd"Rückgabewerte, umbrochen werden, "abcdabc"wodurch unsere Tabelle kleiner bleibt
  • Die Karte übersetzt "x"und "i"an dem Vorsprung 1+, die der Funktion entspricht , {1+x}jedoch kürzer.
  • Die Karte wird "d"in die Projektion übersetzt , die -1+der Funktion entspricht, {-1+x}jedoch kürzer ist.
  • Die Karte übersetzt "k"und "s"in die Funktion{x*x}
  • Die Map übersetzt "c"und "o"in die Ausgabefunktion, {-1@$x;x}die wiederum in K6 etwas länger ist: {""0:,$x;x}Beide geben jedoch ihre Ausgabe gefolgt von einer neuen Zeile aus und geben dann das Argument zurück.
  • .zs ist Selbstrekursion. In K6 können wir einfach sagen, o`was kürzer ist.
Geocar
quelle
8

Perl 5 , 90 Bytes

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

Probieren Sie es online!

Vielen Dank an @xfix für seine Hilfe! 4 Bytes gespart dank @Xcali !

Dom Hastings
quelle
1
Ihr Programm wird gedruckt, 1wenn der Akku überläuft. Außerdem können Sie Ihr Programm um fünf Zeichen verkürzen, indem $aauf $?(die initialisiert wird 0, und wird sich nicht ändern , bis Sie einen externen Programm von Perl laufen).
Konrad Borowski
Ahhhh, ich habe nach einer Variablen gesucht, die ich verwenden könnte, perfekt, danke! Was das Überlaufen betrifft, habe ich es nicht bemerkt, da es nur passiert, wenn Sie isssoals ein Befehl ausgeführt werden, nicht wenn Sie jeden einzeln ausführen ... Ich werde dies später genauer betrachten und es mit Sicherheit verwenden $?. Vielen Dank!
Dom Hastings
Ich denke also, ich habe eine ältere Version im Codeabschnitt oben mit ''anstatt mit ""so belassen , wenn die mit perl -e '...'der Map verwendete mit dem Ergebnis enden würde s///. Danke noch einmal!
Dom Hastings
OK, du bist der kürzeste.
Marinus
1
Nicht mehr die kürzeste Antwort.
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){...} - Setzen Sie den Akku auf 0 und wiederholen Sie die Schleife für immer
  • read-host '>>' - Holen Sie sich die Benutzereingabe mit Eingabeaufforderung >>
  • [char[]](...) - Konvertieren Sie die Benutzereingaben in ein Array von Zeichen
  • |%{...} - Führe {}für jeden Charakter aus , was drin ist
  • switch -r($_) - Regex-Schalter für jedes Zeichen
  • "i|x"{$x++} - Akkumulator angleichen ioder x- erhöhen
  • "d"{$x-=!!$x} - match d- verringern $xum !!$x, was ist, 0wenn $xist 0, und 1sonst. Dadurch wird sichergestellt, dass der Akku niemals erreicht -1.
  • "s|k"{$x*=$x} - Spiel soder k- Quadrat
  • "o|c"{$x} - den Akku abgleichen ooder c- ausgeben
  • $x*=$x-ne256- Multiplizieren Sie den Akku mit, 0wenn dies der Fall ist 256oder auf 1andere Weise

Beispielausgabe

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

Ich vermute, dass die Implementierung von read-hosthostspezifisch ist, sodass dieser Powershell-Host (ConsoleHost) :an die angegebene Eingabeaufforderung angehängt wird .

Danko Durbić
quelle
Nett! !!$xIch liebe das Dekrement von , schade, dass ich das nicht nutzen kann ...
Dom Hastings
Hey Danko, könntest du bitte eine Testausgabe posten? Ich glaube nicht, dass ich Power Shell auf Nicht-Windows testen kann ... (Bitte korrigieren Sie mich, wenn ich mich irre!)
Dom Hastings
Ich habe einige Testausgaben zur Antwort hinzugefügt.
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]

Schönere Version:

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
quelle
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-
quelle
Sie könnten wahrscheinlich einige Zeichen speichern, indem Sie eund vin Operatoren ändern . Ich habe auch versucht, neu zu schreiben vund gdamit der Parameter xin IO bleibt, printusw. aufgehoben zu werden. Ich habe es nicht geschafft, es zum Laufen zu bringen, aber ich denke, das könnte ein guter Ort für jemanden sein, der sein Haschisch kennt.
Shiona
@shiona: Ja, das Problem beim Speichern IOist, dass sie entweder zu oft drucken (weshalb ich sie r nanstelle von verwendet habe x) oder nicht genug, weil der Wert nie abgefragt wird. So wie ich ändern würde eund vin Betreiber?
Ry
Ich hatte die gleichen Probleme beim Drucken. Was kommt zu Operatoren, die Sie tun können (am Beispiel von e) 'i'%x=x+1;'d'%x=x-1... und rufen Sie es einfach in v auf do n<-x;r$w$o%n. Der Grund, warum Operatoren Platz sparen, ist, dass sie keine Leerzeichen in ihrer Umgebung benötigen.
Shiona
@shiona: Oh! Guter Anruf, danke!
Ry
Kein Problem. Ich dachte zuerst darüber nach, eine eigene Antwort zu erstellen, aber da ich meine großen Ideen nicht umsetzen konnte, dachte ich, es wäre einfach unhöflich, genau den gleichen Code mit einer anderen Notation für die gleichen Funktionen zu posten.
Shiona
4

Rubin, 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;'}}

Beispielsitzung (wie Ihre):

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
>>
Türknauf
quelle
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
quelle
Meine Version ist kürzer. Ich habe die Karte komprimiert, auf die ich mich verlassen habe ? Um Werte nach "Wrapping" zu klassifizieren, verwenden Sie stattdessen eine Rekursion und stattdessen einen funktionalen Interpreter.
Geocar
4

Ada

Hier ist eine Ada-Implementierung für die wenigen, die sich für diese Sprache interessieren. Ich habe einige Zeit gebraucht, um einige der Best Practices von Ada anzuwenden (z. B. die Verwendung von Indefinite_Holders anstelle von Access) und um zu verstehen, wie Deadfish funktionieren muss.

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;

Und die Ausgabe:

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

Wenn einige Leute, die in Ada experimentiert haben, mir Optimierungshinweise geben könnten, wäre ich dankbar.

Jérémy Ruelle
quelle
1
Willkommen bei PPCG! Das Ziel von Code-Golf ist es, den kürzestmöglichen Code zu erstellen, und Sie sollten die Größe
Ihres
4

C 159 Zeichen

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

Ich habe einen anderen Ansatz ausprobiert, der auf dem Einrichten einer Nachschlagetabelle für die Befehlsdecodierung basiert, aber das endete leider länger ( 169 ). Ich habe es mit einbezogen, da sich jemand eine clevere Einstellung einfallen lassen könnte, um die Größe zu reduzieren. (Muss ohne Argumente ausgeführt werden)

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

Dies gibt eine neue Zeile nach dem aus >>, aber das OP hat nicht gesagt, dass dies nicht erlaubt ist. Nicht mehr!

Dank GlitchMr, minitechund golfer9338!

jazzpi
quelle
1
Sie können lambdaanstelle von defeine Funktion verwenden, die sofort zurückkehrt.
Konrad Borowski
x in(-1,256)speichert zwei Zeichen. Alternativ s=lambda x:"a=%d"%(x!=-1and x!=256and x)könnten einige sparen.
Ry
1
Sie könnten stattdessen entfernen print(">>")und verwenden for i in input(">>"); input()Ermöglicht die Angabe einer Eingabeaufforderung. Dann wird es keine neue Zeile mehr geben >>und Sie speichern Zeichen.
golfer9338
Ich denke, Ihre Punktzahl sollte im Moment um ein Zeichen kürzer sein . Bitte doppelklicken, aber ich bekomme 161 anstatt der angegebenen 162: Zeilen mit 3 + 40 + 8 + 107 plus 3 Zeilen für neue Zeilen. Um ehrlich zu sein, ich bin eifersüchtig, denn so oder so sind Sie ein paar Zeichen kürzer als meine C-Antwort. Prost!
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")}}

Ungolfed-Version:

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

Beispielsitzung (im interaktiven Modus):

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

Python 3, 141

Ich weiß, dass ich zu spät bin, aber ich wollte die Gelegenheit nutzen, um eine kürzere Python-Version (und meinen ersten CodeGolf-Versuch) zu veröffentlichen. :)

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,'')+')')

Die print-Anweisung war dafür etwas knifflig. Wenn die Eingabeaufforderung mit einem Leerzeichen enden muss, fügen Sie der Zählung ein Zeichen hinzu. :)

Erläuterung

v ist der Akku.

mprüft, ob der angegebene Wert -1oder ist256 . Wenn ja, 0wird der Wert ansonsten zurückgegeben.

In den folgenden Zeilen werden die Operationen den entsprechenden Variablen zugewiesen (da einige dieselbe Bedeutung haben (wie iund x), ist dies kürzer als das Instanziieren eines neuen Wörterbuchs). Diese werden dann im verwendetexec Folgenden verwendet.

while 1: ist die Hauptschleife

Jetzt fängt der Spaß an. Wie bei der @ jazzpi -Lösung wird jedes Zeichen der Eingabe durchlaufen . locals()ist das Wörterbuch aller aktuellen (sichtbaren) Variablen. Mit .get(n,'')dem entsprechenden Schlüssel wird in die Exec-Zeichenkette (eine leere Zeichenkette, falls der Schlüssel (= andere Eingabe) nicht gefunden wurde) gesetzt. Dies wird dann, wenn es ausgeführt wird, verkettet vund weitergeleitet m. Der Rückgabewert wird erneut gespeichert v.

Kurzes Beispiel:

Sei n = 'i'( n= Eingabe-Zeichen), verlassen wir '+1'den localsBlock wie idie Variable mit dem Wert '+1'.
Die Zeichenfolge für die execals sieht wie folgt aus : 'v=m(v+1)'.
Vielleicht ist es jetzt einfacher zu sehen, dass es beim Ausführen mden Wert von v+1aufruft und seine Ausgabe in speichertv erneut .

Wiederholen Sie diesen Vorgang, bis Sie sich langweilen. :)

Dave J
quelle
Mir ist klar, dass ich SEHR spät zur Party komme, aber das Lambda für m kann y*(-1!=y!=256)für -3 Bytes sein
Setzen Sie Monica
nur 5 Jahre :) Vielen Dank für den Input. Ich bin zu faul, um die Antwort nicht zu korrigieren, aber ich werde es im Hinterkopf behalten
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

Das ist ordentlich, aber auch ziemlich unkompliziert. Hier ist eine längere, coolere Version:

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)

Mit 190 Zeichen ist dies möglicherweise nicht die wettbewerbsfähigste Antwort. Auf der anderen Seite sind Coroutinen ziemlich radikal und ich suche immer nach einer Ausrede, um sie zu benutzen (und zu teilen)

Dingusman
quelle
3

TI-BASIC, 104 107 102 100 98

Für Taschenrechner der Serie TI-83 + / 84 +.

Nennen Sie das prgmD ; es überläuft schließlich den Stapel, indem es sich selbst aufruft. Ersetzen Sie die Rekursion durch ein While 1, um dieses Problem zu beheben.

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 ist standardmäßig 0, führen Sie dies also entweder mit einem neu gelöschten Taschenrechner aus oder speichern Sie 0 bis Y manuell, bevor Sie dies ausführen.

Schade, dass die Kleinbuchstaben (in den String-Literalen) jeweils zwei Bytes sind; Andernfalls wäre dies kürzer als die Antwort von Dom Hastings.

BEARBEITEN: Fehler beim Teilen durch Null (0 ^ 0) auf Kosten von drei Bytes behoben.

107 -> 102: Speichert mit dem Trick der imaginären Potenzierung vier Bytes (einschließlich 1 aus Klammern und -1 aus der Verlängerung der Suchzeichenfolge) und verwendet Y anstelle von X, für dessen Initialisierung ein Byte weniger benötigt wird.

Lirtosiast
quelle
2

Nachschrift 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
quelle
2

C (224 212 Zeichen)

Dies ist wahrscheinlich eine schlechte Sprachwahl, aber na ja. Es ist nicht so, dass eine Sprache wie C besser kann als eine dynamische Programmiersprache. Auf Clang müssen Sie einen Wert für angeben return(dies ist für gcc nicht erforderlich).

#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
quelle
Wäre es nicht kürzer, nur die zu entfernen define qund nur zu verwenden printf?
Türklinke
@DoorknobofSnow Eigentlich nein. qwird 3 mal verwendet, define qspart also ~ 2 Zeichen.
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 _

Nicht das Schlimmste, nicht das Beste.

HINWEIS: Wie von @mniip gemeldet, funktioniert dies256or möglicherweise nicht in Ihrem Interpreter. Mehr Infos in Kommentaren.

(mehr oder weniger) Lesbare Version:

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 _

Ausgabe:

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

Edit: danke an @mniip für 2 Zeichen Optimierung: until nil->until _

Egor305
quelle
repeat until x(x ist nil wie nicht definiert) ist 2 Zeichen kürzer und while 1 do endhat exakt die gleiche Länge. Was ist das für eine Lua-Version?256orIn meinem Interpreter ist die Syntax ungültig
Mniip
@mniip Danke für den Hinweis zu repeat until x. Ich verwende die neueste Windows-Binärdatei von hier . Wie Sie sehen können, a=a+1 elseifhaben Sie Platz. Das liegt daran, dass ees sich um eine hexadezimale Ziffer handelto in 256ornicht ist, so mein Dolmetscher nimmtor als eine andere Anweisung / Block / howYouCallIt.
Egor305
ja so ziemlich außerdem 256orauch 0repeatund 1then; Ich verwende das offizielle lua von lua.org, Ihr Code wird weder in 5.1, 5.2 noch in 5.3
kompiliert
2

Haskell , 186 178 Bytes

Dies muss mit runhaskell(oder in ghci) ausgeführt werden, da beide standardmäßig den Wert auf setzen BufferMode, NoBufferingwodurch eine ganze Menge Bytes gespart werden:

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

Probieren Sie es online!

Erläuterung

Dies definiert einen neuen Betreiber state # source(die Unveränderlichkeit Erklärung ermöglicht es uns , Klammern zu fallen , wenn sie in Verbindung mit anderen Operatoren (+), (-), (^), (:)und (>>)):

  • Die ersten beiden Zeilen "fixieren" die Zustände -1und256
  • es stimmt dann mit dem ersten Zeichen überein und handelt danach
  • Sobald es keine Zeichen mehr gibt ( r#_), werden neue gelesen und der alte Zustand wird beibehalten

Um den Prozess zu starten, initialisieren wir den Zustand mit 0 und lesen eine neue Quellzeile, dh. Beginnen Sie mit einer leeren Quelle:

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

Windows Batch, 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

Ignoriert erfolgreich andere Befehle. Wirklich wurde aufgebläht, ohne zu habenor arbeiten zu müssen ...

Bearbeiten:

Fest:

  • Kein Echo mehr auf alle Befehle
  • Hat es tatsächlich geschafft, mit / a zu rechnen
  • Reset auf -1
  • Eingang nach jedem Zyklus zurücksetzen

Dies kostete 52 Zeichen.

Nicht behoben:

  • Beim Quadrieren von 0 wird "0 * 0" in a geschrieben.
  • Wenn Sie Leerzeichen eingeben (oder nichts eingeben, wenn Sie es gerade geöffnet haben), stürzt das Skript ab.
  • Sie MÜSSEN jeweils ein Zeichen eingeben.
Timtech
quelle
2
Dieser funktioniert einfach überhaupt nicht (Windows 7). Ich will kein Arschloch sein, aber hast du das getestet?
Marinus
@marinus Es wurde behoben.
Timtech
1

Windows-Befehlsskript - 154

Abusin unbekannte Merkmale bis zur max.

@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
quelle
1

> <> 258 Bytes

Ich habe eine andere> <> Antwort gemacht, da ich die Phase nicht testen konnte und sie ohnehin vorab gestapelte Befehle verwendete, anstatt eine Shell zu emulieren.

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

Es kann durchaus Golf gespielt werden, aber ich bin mir nicht sicher, ob ich den nötigen Mut zum Wahnsinn habe !

Ich habe es mit dem offiziellen Interpreter unter Python 3.5 unter Cygwin unter Windows 7 getestet und konnte den Testlauf nachvollziehen:

$ 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

Falls Sie es auf Ihrem Computer nicht ausführen können (Eingabe scheint schwierig zu sein) oder es nur ohne andere Software ausprobieren möchten, können Sie die folgende Version im Online-Interpreter verwenden .

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

Es ignoriert offensichtlich \ n und EOF, da Sie sie nicht im Online-Interpreter eingeben können, sondern sich so verhalten, als ob die Eingabetaste nach jedem Ausgabebefehl gedrückt worden wäre.

Aaron
quelle
1

C (gcc) 139 Bytes

Kompilieren Sie mit -Dk="_nZZiaeY"(in der Byteanzahl enthalten). -2 Bytes, wenn die Eingabeaufforderung >>\nzulässig ist.

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

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

quelle
1

Keg , 68B

0{'::"ÿ1+=$0<+['_0"] \>\>\
,,,,?:o=[':."]:i=['1+"]:d=['1-"]:s=[':*"
EIN
quelle
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

Wenn ich nur diesen lästigen hFlush stdoutAnruf loswerden könnte ! Ohne diese Option wird die Eingabeaufforderung erst angezeigt, wenn eine oOperation ausgeführt wird. Irgendein Rat?

danmcardle
quelle
Sie können das loswerden, hFlushindem Sie verwenden, runhaskellanstatt zu kompilieren (siehe meine Antwort ), aber für diese Lösung ist es nicht gültig und es treten Fehler auf.
15.
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>

Die Ausgabe ist etwas lückenhaft (Verlauf / Sitzung wird in einem Textbereich angezeigt, und bei aktivierter Fehlerberichterstattung werden viele Warnungen gedruckt), aber alles funktioniert

Einacio
quelle
0

> <>, 239

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

Der Anfangsstapel ist die Eingabe. Sie können es hier online ausprobieren .

Phase
quelle
0

Golf-Basic 84, 88 Zeichen

: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

Fordert wie in mindestens drei anderen Lösungen jeweils einen Befehl auf. Hier ist ein Testlauf für xiskisc:

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

Auch xisksogibt 0, wie es sollte.

Timtech
quelle
Welche anderen Lösungen fordern jeweils einen Befehl an?
Ry
1
Ich habe den Haskell geschrieben, und nein, das tut es nicht. Das Perl auch nicht, also bin ich mir nicht sicher, wovon du sprichst.
Ry
1
Dies entspricht nicht den E / A-Regeln.
Marinus
1
Befolgen Sie immer noch nicht die Regeln und verwenden Sie Großbuchstaben statt Kleinbuchstaben.
Lirtosiast
1
Wenn Sie mit TI-BASIC vertraut sind, werden nur Großbuchstaben unterstützt.
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)

Dies kann wahrscheinlich Golf gespielt werden. Node.js beweist erneut, dass es sich um eine seltsam getarnte Ausführlichkeit handelt. Code erklärt:

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
BürgermeisterMonty
quelle
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;}}}}}

wäre 283 Byte, wenn die Verwendung und Klassendeklaration usw. weggelassen werden könnten, indem nur eine Funktionsdefinition angegeben wird

Robin B
quelle