Napisz interaktywnego tłumacza Deadfish

30

Deadfish to żart „język programowania” z czterema poleceniami. Ponieważ strona Esolang jest nieco sprzeczna, a tłumacze na tej stronie nie działają dokładnie tak samo, należy wprowadzić następującą odmianę:


Specyfikacja

  1. Jest akumulator, który ma co najmniej 16 bitów, więcej jest dozwolone, ale mniej nie. Liczby ujemne nie muszą być obsługiwane. Akumulator jest w 0momencie uruchomienia programu.
  2. Istnieją następujące dwa zestawy czterech poleceń, a twój program musi obsługiwać oba jednocześnie.
      Standard Deadfish │ Wariant XKCD │ Znaczenie
      ─────────────────────┼──────────────────┼───────── ───────────────────────────
            i │ x │ Akumulator przyrostowy
            d │ d │ Akumulator zmniejszający się
            s │ k │ Kwadrat (acc = acc * acc)
            o │ c │ Akumulator wyjściowy, jako liczba
    
  3. Jeśli po wykonaniu polecenia akumulator jest ustawiony na albo, -1albo 256akumulator musi zostać zresetowany do zera. Pamiętaj, że nie jest to normalne zawijanie. Jeśli powiedzmy, że akumulator jest 20, a spolecenie zostanie wykonane, akumulator powinien być 400później. Podobnie, jeśli akumulator jest 257i dpolecenie jest uruchomione, akumulator powinien się stać 0.
  4. Wszelkie dane wejściowe, które nie są jednym z tych poleceń, należy zignorować.

Programy testowe

  • xiskso powinien wyjść 0
  • xiskisc powinien wyjść 289

I / O

Twój program powinien wyświetlić się monit: >>. Monit musi znajdować się na początku nowej linii. Następnie powinien odczytać wiersz wprowadzony przez użytkownika i uruchomić podane polecenia od lewej do prawej. Podczas wyprowadzania liczb należy je rozdzielić. Tj. 12 34Jest w porządku, 12,34jest w porządku,

12
34 

jest OK, ale 1234nie jest.

Twój program powinien robić to w pętli, przynajmniej dopóki nie EOFzostanie osiągnięty.

Przykładowa sesja:

>> xiskso
0
>> xiskisc
289
>> ddddo ddddo
285
281
>> ddddo ddddo
277
273
>> dddddddo
266
>> dddddddddo
257
>> do
0
>> do
0
>> io
1
>> 
marinus
źródło
Z powodu monitu o wprowadzenie danych nie mogę używać GolfScript :-(
ProgramFOX
@ProgramFOX: Czy możesz używać wprowadzania ruby, prawda?
marinus,
Zgodnie z samouczkiem GolfScript nie można pytać o dane wejściowe w GolfScript, wszystkie dane wejściowe pochodzą z STDIN.
ProgramFOX,
@ProgramFOX: Myślałem, że coś takiego #{STDIN.gets}zadziała, ale tak naprawdę nie działa.
marinus
Czy zamiast tego wolno nam wprowadzać duże litery?
lirtosiast

Odpowiedzi:

6

K, 77 bajtów

  {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

Zauważ, że to K4 . Rozwiązanie K6 jest nieco dłuższe, ponieważ czasowniki IO są dłuższe, nawet jeśli wszystko inne jest lepsze:

{""0:">>";0{x*^-1 256?x:y@x}/("xkcdiso"!7#(1+;{x*x};{""0:,$x;x};-1+))@0:"";o`}`
  • ""0:wypisuje i zwraca swój argument. Uwaga w K4 mamy po prostu zastosowanie do 1 .
  • 0 f/ args wykazuje zmniejszenie o wartości początkowej, tj f[f[0;first arg];second arg]…
  • {x*2=-1 256?x…klasyfikuje x do 0 (dla -1), 1 (dla 256) i 2 dla wszystkich innych wartości. 2=oznacza, że ​​otrzymujemy 1niesklasyfikowane wartości, a w 0przeciwnym razie pomnożenie przez xjest krótsze niż warunkowe. W K6 możemy zrobić trochę lepiej, ponieważ {x*^-1 256?x:y@x}opiera się na fakcie, że -1 256?xzwraca 0N(null) i ^wykrywa null.
  • „Parser” to mapa "xkcdiso"zamiast sugerowanej kolejności, ponieważ 7#obejmie cztery argumenty, tj. 7#"abcd"Zwroty, "abcdabc"dzięki czemu nasza tabela będzie mniejsza
  • Mapa tłumaczy się "x"i "i"wyświetla rzut, 1+który jest równoważny funkcji, {1+x}ale krótszy.
  • Mapa tłumaczy "d"się na rzut, -1+który jest równoważny funkcji, {-1+x}ale krótszy.
  • Mapa tłumaczy "k"i "s"do funkcji{x*x}
  • Mapa tłumaczy "c"i "o"do funkcji wyjściowej, {-1@$x;x}która ponownie w K6 jest nieco dłuższa: {""0:,$x;x}ale oba wypisują swoje dane wyjściowe, po których następuje nowa linia, a następnie zwraca argument.
  • .zs jest rekursją wewnętrzną . W K6 możemy po prostu powiedzieć, o`która jest krótsza.
geocar
źródło
8

Perl 5 , 90 bajtów

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

Wypróbuj online!

Dzięki @xfix za pomoc w tej sprawie wcześniej! Zaoszczędź 4 bajty dzięki @Xcali !

Dom Hastings
źródło
1
Twój program drukuje, 1gdy nastąpi przelanie akumulatora. Możesz także skrócić swój program o pięć znaków, zmieniając $ana $?(który jest inicjowany 0i nie zmieni się, dopóki nie uruchomisz zewnętrznego programu z Perla).
Konrad Borowski,
Ahhhh, szukałem zmiennej, której mógłbym użyć, idealnie, dziękuję! Jeśli chodzi o przepełnienie, nie zauważyłem tego, ponieważ zdarza się to tylko wtedy, gdy uruchamiasz isssojako jedno polecenie, a nie jeśli wykonujesz każde z osobna ... Zajmę się tym później i na pewno skorzystam $?. Dziękuję Ci!
Dom Hastings,
Myślę więc, że zostawiłem starszą wersję w sekcji kodu u góry, ''zamiast tego "", gdy użyty z perl -e '...'mapą skończy się wynikiem s///. Dzięki jeszcze raz!
Dom Hastings,
OK, jesteś najkrótszy.
marinus
1
Nie jest już najkrótszą odpowiedzią.
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){...} - ustaw akumulator na 0 i zapętlaj na zawsze
  • read-host '>>' - uzyskaj informacje od użytkownika z pytaniem >>
  • [char[]](...) - przekonwertować dane wejściowe użytkownika na tablicę znaków
  • |%{...} - wykonaj to, co jest w środku {}dla każdej postaci
  • switch -r($_) - przełącznik regex dla każdej postaci
  • "i|x"{$x++} - dopasuj ilub x- zwiększ akumulator
  • "d"{$x-=!!$x} - dopasuj d- pomniejsz $xo !!$x, co będzie, 0jeśli $xbędzie 0, i 1inaczej. Dzięki temu akumulator nigdy nie osiągnie -1.
  • "s|k"{$x*=$x} - dopasowanie slub k- kwadrat
  • "o|c"{$x} - dopasuj olub c- wyjmij akumulator
  • $x*=$x-ne256- pomnożyć akumulator przez, 0czy jest, 256czy przez 1inny sposób

Przykładowe dane wyjściowe

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

read-hostWydaje mi się, że implementacja jest specyficzna dla hosta, więc ten host Powershell (ConsoleHost) dołącza :się do określonego monitu.

Danko Durbić
źródło
Miły! Uwielbiam dekrement !!$x, szkoda, że ​​nie mogę tego wykorzystać ...
Dom Hastings,
Hej, Danko, czy mógłbyś opublikować jakieś wyniki testu? Nie sądzę, żebym mógł przetestować powłokę mocy w systemach innych niż Windows ... (popraw mnie, jeśli się mylę!)
Dom Hastings,
Dodałem trochę wyników testu do odpowiedzi.
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]

Ładniejsza wersja:

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
źródło
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-
źródło
Prawdopodobnie może uratować kilka znaków poprzez zmianę ei vdo operatorów. Próbowałem również przepisać vi gżeby parametr xpozostał w IO, printitd. Został podniesiony. Nie udało mi się go uruchomić, ale myślę, że może to być dobre miejsce dla kogoś, kto zna ich haskell.
shiona
@shiona: Tak, chodzi o IOto, że albo drukują zbyt często (dlatego użyłem r nzamiast x), albo za mało, ponieważ o wartość nigdy nie prosi się… Jak więc zmienić się ei vzostać operatorem?
Ry-
Miałem te same problemy z drukowaniem. Co możesz zrobić z operatorami (na przykładzie e) 'i'%x=x+1;'d'%x=x-1... I po prostu wywołaj to w v do n<-x;r$w$o%n. Powodem, dla którego operatorzy oszczędzają miejsce, jest to, że nie wymagają odstępów wokół nich.
shiona
@shiona: Oh! Dobry telefon, dziękuję!
Ry-
Nie ma problemu. Najpierw pomyślałem o udzieleniu własnej odpowiedzi, ale ponieważ nie mogłem uruchomić moich wielkich pomysłów, pomyślałem, że byłoby to niegrzeczne wysyłanie dokładnie tego samego kodu z inną notacją dla tych samych funkcji.
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;'}}

Przykładowa sesja (taka sama jak Twoja):

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
>>
Klamka
źródło
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
>>
tartin
źródło
Moja wersja jest krótsza. Kompresowałem mapę, polegałeś na ? aby zaklasyfikować do wartości „zawijanie”, użyliśmy rekurencji zamiast while i funkcjonalnego interpretera zamiast zmiany.
geocar
4

Ada

Oto implementacja Ada dla kilku osób zainteresowanych tym językiem. Zajęło mi sporo czasu, aby zastosować niektóre z najlepszych praktyk Ady (np. Użycie Indefinite_Holders zamiast dostępu), a także w pełni zrozumieć, jak Deadfish musi działać.

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;

A wynik:

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

Byłbym wdzięczny, gdyby niektóre osoby eksperymentujące w Adzie dały mi wskazówki dotyczące optymalizacji.

Jérémy Ruelle
źródło
1
Witamy w PPCG! Celem code-golfa jest stworzenie możliwie najkrótszego kodu, a nagłówek powinien zawierać rozmiar twojego programu (tutaj 1396 bajtów)
TuxCrafting
4

C, 159 znaków

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

Próbowałem innego podejścia opartego na ustawianiu tabeli przeglądowej do dekodowania instrukcji, ale niestety skończyło się to dłużej ( 169 ). Włączyłem to, ponieważ ktoś może wymyślić sprytną modyfikację, aby zmniejszyć rozmiar. (Musi być uruchamiany bez żadnych argumentów)

#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();
}
Robaczek świętojański
źródło
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
źródło
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,""))

Daje to nowy wiersz po >>, ale OP nie powiedział, że to niedozwolone. Nigdy więcej!

Dzięki GlitchMr, minitechi golfer9338!

jazzpi
źródło
1
Możesz użyć lambdazamiast deffunkcji, która natychmiast zwraca.
Konrad Borowski,
x in(-1,256)zapisuje dwie postacie. Alternatywnie, s=lambda x:"a=%d"%(x!=-1and x!=256and x)może zaoszczędzić trochę.
Ry-
1
Zamiast tego możesz usunąć print(">>")i użyć for i in input(">>"); input()pozwala określić monit. Wtedy nie będzie już nowego wiersza >>i zapisujesz postacie.
golfer9338
Myślę, że twój wynik powinien być teraz o jeden charakter krótszy . Proszę dwukrotnie sprawdzić, ale dostaję liczbę 161 zamiast wysłanych 162: wiersze 3 + 40 + 8 + 107 oraz 3 nowe wiersze. Prawdę mówiąc, jestem zazdrosny, ponieważ tak czy inaczej, jesteś o kilka znaków krótszy niż moja odpowiedź C. Twoje zdrowie!
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")}}

Wersja bez golfa:

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

Przykładowa sesja (w trybie interaktywnym):

>> xiskso
0
>> xiskisc
289
>> ddddo ddddo
285
281
>> ddddo ddddo
277
273
>> dddddddo
266
>> dddddddddo
257
>> do
0
>> do
0
>> io
1
>> 
Sven Hohenstein
źródło
3

Python 3, 141

Wiem, że się spóźniłem, ale chciałem skorzystać z okazji, aby opublikować krótszą wersję Pythona (i moją pierwszą próbę 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,'')+')')

Instrukcja print była do tego dość trudna. Jeśli monit musi kończyć się spacją, dodaj jeden znak do liczby. :)

Wyjaśnienie

v jest akumulator.

msprawdza, czy podana wartość to -1lub 256. Jeśli tak, 0zostanie zwrócona, w przeciwnym razie wartość.

W kolejnych wierszach operacje są przypisane do odpowiednich zmiennych (ponieważ niektóre mają to samo znaczenie (jak ii x), jest to krótsze niż tworzenie nowego słownika). Są one następnie używane execponiżej.

while 1: jest główną pętlą

Teraz zaczyna się zabawa. Podobnie jak rozwiązanie @jazzpi , iteruje się po każdym znaku wejściowym. locals()jest słownikiem wszystkich bieżących (widocznych) zmiennych. Z .get(n,'')odpowiednim kluczem zostanie wstawiony do ciągu wykonawczego (pusty ciąg, jeśli klucz (= inne dane wejściowe) nie został znaleziony). To wtedy zostanie wykonane, połączone vi przekazane m. Zwracana wartość zostanie ponownie zapisana v.

Krótki przykład:

Be n = 'i'( n= input-char), '+1'wychodzimy z locals-block, podobnie jak izmienna o wartości '+1'.
Ciąg na execniż wygląda następująco: 'v=m(v+1)'.
Być może teraz łatwiej jest zauważyć, że podczas wykonywania zadzwoni mz wartością v+1i zapisze vponownie swoje wyjście .

Powtarzaj to, aż się nudzisz. :)

Dave J.
źródło
Zdaję sobie sprawę, że jestem BARDZO spóźniony na imprezę, ale lambda na m może wynosić y*(-1!=y!=256)-3 bajty
przywróć Monikę
tylko 5 lat :) dziękuję za wkład. Jestem zbyt leniwy, aby nie naprawić odpowiedzi, ale będę o tym pamiętać
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

Jest to schludne, ale także dość proste. Oto dłuższa, fajniejsza wersja:

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)

Ważący 190 znaków, być może nie jest to najbardziej konkurencyjna odpowiedź. Z drugiej strony, coroutines są dość rad i zawsze szukam pretekstu do ich używania (i dzielenia się)

dingusman
źródło
3

TI-BASIC, 104 107 102 100 98

Do kalkulatorów serii TI-83 + / 84 +.

Nazwij to prgmD; ostatecznie przepełnia stos, wywołując siebie. Zastąp rekurencję While 1kosztem dwóch bajtów, aby to naprawić.

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 jest domyślnie 0, więc albo uruchom to za pomocą świeżo wyczyszczonego kalkulatora, albo zapisz 0 do Y ręcznie przed uruchomieniem tego.

Szkoda, że ​​małe litery (w literałach łańcuchowych) mają po dwa bajty; inaczej byłoby to krótsze niż odpowiedź Dom Hastings.

EDYCJA: Naprawiono błąd dzielenia przez zero (0 ^ 0) kosztem trzech bajtów.

107 -> 102: Użyłem sztucznej potęgi wykładniczej, aby zapisać cztery bajty (w tym 1 z nawiasów i -1 z wydłużenia łańcucha wyszukiwania) i użyłem Y zamiast X, który zajmuje jeden bajt mniej do inicjalizacji.

lirtosiast
źródło
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

Nie golfowany:

/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
źródło
2

C (224 212 znaków)

To prawdopodobnie zły wybór języka, ale no cóż. To nie jest tak, że język taki jak C radzi sobie lepiej niż jakiś dynamiczny język programowania. W Clang musisz podać wartość dla return(nie jest to konieczne w przypadku 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
źródło
Czy nie byłoby krótsze usunięcie define qi użycie printf?
Klamka
@DoorknobofSnow Właściwie nie. qjest używany 3 razy, więc define qzapisuje ~ 2 znaki.
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 _

Nie najgorsze, nie najlepsze.

UWAGA: jak informuje @mniip, 256or może nie działać w twoim tłumaczu . Więcej informacji w komentarzach.

(mniej więcej) Wersja do odczytu:

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 _

Wydajność:

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

Edycja: dzięki @mniip za optymalizację 2 znaków : until nil->until _

Egor305
źródło
repeat until x(x jest zerowy, jak nie został zdefiniowany) jest o 2 znaki krótszy i while 1 do endma dokładnie taką samą długość, poza tym, co to jest wersja lua? 256orjest niepoprawna składnia w moim
tłumaczu
@mniip Dzięki za podpowiedź repeat until x. Używam najnowszy Windows binarny z tutaj . Jak widać a=a+1 elseifmasz miejsce. To dlatego, że ejest cyfrą szesnastkową, podczas gdy ow 256ornie jest, więc mój interpreter przyjmuje orjako inną instrukcję / blok / howYouCallIt.
Egor305,
tak, właściwie poza tym 256or, także 0repeati 1then; Używam oficjalnej lua z lua.org, twój kod nie kompiluje się ani w wersji 5.1, 5.2, ani 5.3
mniip
2

Haskell , 186 178 bajtów

To musi być prowadzony z runhaskell(lub wewnątrz ghci) ponieważ oba ustawić BufferModeaby NoBufferingdomyślnie który sejfy sporo bajtów:

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

Wypróbuj online!

Wyjaśnienie

To definiuje nowy operator state # source(deklaracja stałość pozwala nam spadać nawiasy podczas używania go w połączeniu z innymi operatorami (+), (-), (^), (:)i (>>)):

  • pierwsze dwie linie „naprawiają” stany -1i256
  • następnie dopasowuje pierwszą postać i działa na nią
  • gdy zabraknie znaków ( r#_), odczytuje nowe i zaczyna od nowa, zachowując stary stan

Aby rozpocząć proces, inicjalizujemy stan 0i odczytujemy nową linię źródłową, tj. zacznij od pustego źródła:

main=0#""
ბიმო
źródło
1

Pakiet 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

Pomyślnie ignoruje inne polecenia. Naprawdę obrzęknął bez konieczności orpracy z ...

Edytować:

Naprawiony:

  • Nigdy więcej echa wszystkich poleceń
  • Sprawiło, że faktycznie robi matematykę z / a
  • Zresetuj na -1
  • Resetuj wejście po każdym cyklu

Kosztowało to 52 znaki.

Nie naprawiono:

  • Kwadrat 0 oznacza „0 * 0” w.
  • Wprowadzanie spacji (lub wprowadzanie niczego, gdy właśnie ją otworzyłeś) powoduje awarię skryptu.
  • POTRZEBUJESZ wprowadzić jeden znak na raz.
Timtech
źródło
2
Ten po prostu nie działa w ogóle (Windows 7). Nie chcę być dupkiem, ale przetestowałeś to?
marinus
@marinus Zostało to naprawione.
Timtech
1

Skrypt poleceń systemu Windows - 154

Wykorzystaj nieznane funkcje do maksimum.

@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
źródło
1

> <> , 258 bajtów

Uczyniłem inną odpowiedź> <>, ponieważ nie mogłem przetestować faz i użyłem poleceń w stosie zamiast emulować powłokę.

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

Można z pewnością być grałem w dół, ale nie jestem pewien, że mam potrzebne insanity odwagę!

Przetestowałem to z oficjalnym tłumaczem działającym pod Pythonem 3.5 pod cygwin pod Windows 7 i mogłem odtworzyć przebieg testowy:

$ 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

Jeśli nie możesz uruchomić go na swoim komputerze (wprowadzanie danych wydaje się trudne) lub po prostu chcesz go wypróbować bez żadnego innego oprogramowania, możesz użyć następującej wersji na tłumaczu 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

Oczywiście ignoruje \ n i EOF, ponieważ nie można wprowadzić ich do interpretera online, ale zachowuje się tak, jakby po każdym poleceniu wyjścia naciśnięto klawisz Enter.

Aaron
źródło
1

C (gcc) , 139 bajtów

Kompiluj z -Dk="_nZZiaeY"(uwzględnione w liczbie bajtów). -2 bajty, jeśli monit >>\njest dozwolony.

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

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

źródło
1

Keg , 68 B.

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

Gdybym tylko mógł pozbyć się tego nieznośnego hFlush stdoutwezwania! Bez niego monit nie będzie wyświetlany, dopóki nie ozostanie wykonana operacja. Jakakolwiek rada?

Danmcardle
źródło
Możesz się go pozbyć hFlush, używając runhaskellzamiast kompilacji (patrz moja odpowiedź ), ale jeśli chodzi o to rozwiązanie, nie jest poprawne i nie ma błędów.
ბიმო
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>

dane wyjściowe są trochę szkicowe (historia / sesja jest wyświetlana w obszarze tekstowym, a przy włączonym raportowaniu błędów drukowanych jest wiele ostrzeżeń), ale wszystko działa

Einacio
źródło
0

> <>, 239

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

Początkowy stos jest wejściem. Możesz spróbować online tutaj .

faza
źródło
0

Golf-Basic 84, 88 znaków

: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

Monituje jedno polecenie na raz, tak jak w co najmniej 3 innych rozwiązaniach. Oto uruchomienie testowe dla xiskisc:

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

Również xisksozwraca 0, tak jak powinno.

Timtech
źródło
Które inne rozwiązania wymagają jednego polecenia na raz?
Ry-
1
Napisałem Haskell, i nie, nie ma. Podobnie jak Perl, więc naprawdę nie jestem pewien, o czym mówisz.
Ry-
1
To nie jest zgodne z regułami We / Wy.
marinus
1
Nadal nie przestrzega zasad i używa wielkich liter zamiast małych.
lirtosiast
1
Jeśli wiesz o TI-BASIC, obsługuje on tylko wprowadzanie wielkich liter.
Timtech,
0

JavaScript (Node.js), 204 bajtów

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)

To może być prawdopodobnie gra w golfa. Node.js ponownie udowadnia, że ​​to dziwna ukryta gadatliwość. Kod wyjaśniony:

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
źródło
0

C #, 311 bajtów

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

miałby 283 bajty, gdyby można było pominąć zastosowania i deklarację klasy itp. poprzez podanie definicji funkcji

Robin B.
źródło