Écrire un interprète interactif de Deadfish


30

Deadfish est un "langage de programmation" blague avec quatre commandes. Étant donné que la page Esolang est un peu contradictoire et que les interprètes de cette page ne fonctionnent pas tous exactement de la même manière, vous devez implémenter la variante suivante:


spécification

  1. Il existe un accumulateur d'une taille d' au moins 16 bits, plus est autorisé, mais moins ne l'est pas. Les nombres négatifs n'ont pas besoin d'être pris en charge. L'accumulateur est au 0démarrage du programme.
  2. Il existe les deux ensembles de quatre commandes suivants, et votre programme doit prendre en charge les deux en même temps.
      Poisson-mort standard Vari Variante XKCD │ Signification
      ─────────────────────┼──────────────────┼───────── ───────────────────────────
            i │ x │ Accumulateur d'incréments
            d │ d │ Décrémenter l'accumulateur
            s │ k │ Carré (acc = acc * acc)
            o │ c │ Accumulateur de sortie, en nombre
    
  3. Si, après avoir exécuté une commande, l'accumulateur est soit -1ou 256, l'accumulateur doit être remis à zéro. Notez que ce n'est pas un bouclage normal. Si, par exemple, l'accumulateur l'est 20et que la scommande est exécutée, l'accumulateur doit l'être 400après. De même, si l'accumulateur est 257et la dcommande est exécutée, l'accumulateur devrait devenir 0.
  4. Toute entrée qui ne fait pas partie de ces commandes doit être ignorée.

Programmes de test

  • xiskso devrait sortir 0
  • xiskisc devrait sortir 289

E / S

Votre programme devrait afficher une invite: >>. L'invite doit être au début d'une nouvelle ligne. Il doit ensuite lire une ligne d'entrée utilisateur et exécuter les commandes données de gauche à droite. Lors de la sortie de nombres, les nombres doivent être séparés. C'est à dire, 12 34est OK, 12,34est OK,

12
34 

est OK, mais 1234ne l'est pas.

Votre programme doit continuer à le faire en boucle, au moins jusqu'à ce qu'il EOFsoit atteint.

Exemple de session:

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

En raison de l'invite de saisie, je ne peux pas utiliser GolfScript :-(
ProgramFOX

@ProgramFOX: Vous pouvez utiliser une entrée rubis non?
marinus

Selon le didacticiel GolfScript, vous ne pouvez pas demander d'entrée dans GolfScript, toutes les entrées proviennent de STDIN.
ProgramFOX

@ProgramFOX: J'aurais pensé que quelque chose comme ça #{STDIN.gets}marcherait mais en effet ça ne marche pas.
marinus

Sommes-nous autorisés à prendre des entrées en majuscules à la place?
lirtosiast

Réponses:


6

K, 77 octets

  {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

Notez que c'est K4 . Une solution K6 est légèrement plus longue car les verbes IO sont plus longs, même si tout le reste est meilleur:

{""0:">>";0{x*^-1 256?x:y@x}/("xkcdiso"!7#(1+;{x*x};{""0:,$x;x};-1+))@0:"";o`}`
  • ""0:imprime et renvoie son argument. Remarque en K4, nous appliquons simplement à 1 .
  • 0 f/ args montre réduire avec une valeur initiale, c.-à-d. f[f[0;first arg];second arg]…
  • {x*2=-1 256?x…classe x en 0 (pour -1), 1 (pour 256) et 2 pour toutes les autres valeurs. 2=signifie que nous obtenons 1des valeurs non classifiées et 0sinon, multiplier par xest plus court qu'un conditionnel. En K6, nous pouvons faire un peu mieux, car nous nous {x*^-1 256?x:y@x}appuyons sur le fait que -1 256?xrenvoie 0N(null) et ^détecte les nulls.
  • Le "parseur" est la carte "xkcdiso"au lieu de l'ordre suggéré car 7#il s'enroulera autour des quatre arguments, c'est-à-dire des 7#"abcd"retours "abcdabc"qui gardent notre table plus petite
  • La carte se traduit "x"et "i"à la projection 1+qui est équivalente à la fonction {1+x}mais plus courte.
  • La carte se traduit "d"par la projection -1+qui est équivalente à la fonction {-1+x}mais plus courte.
  • La carte se traduit "k"et "s"à la fonction{x*x}
  • La carte se traduit "c"et "o"à la fonction de sortie {-1@$x;x}qui à nouveau dans K6 est légèrement plus long: {""0:,$x;x}mais à la fois imprimer sa sortie suivie d'un saut de ligne, puis retourne l'argument.
  • .zs est auto- récursif . En K6, nous pouvons simplement dire o`lequel est le plus court.

8

Perl 5 , 90 octets

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

Essayez-le en ligne!

Merci à @xfix pour son aide à ce sujet auparavant! 4 octets enregistrés grâce à @Xcali !


1
Votre programme s'imprime 1lorsque l'accumulateur déborde. De plus, vous pouvez raccourcir votre programme de cinq caractères, en changeant $aen $?(qui est initialisé en 0, et ne changera pas tant que vous n'aurez pas exécuté un programme externe depuis Perl).
Konrad Borowski

Ahhhh, je cherchais une variable que je pouvais utiliser, parfaite, merci! Quant au débordement, je ne l'ai pas remarqué car il ne se produit que si vous exécutez isssoune seule commande, pas si vous les exécutez séparément ... J'y reviendrai plus tard et j'utiliserai certainement $?. Merci!
Dom Hastings

Je pense donc que j'ai laissé une version plus ancienne dans la section de code en haut avec ''au lieu de ""donc lorsqu'elle est utilisée avec perl -e '...'la carte se terminerait par le résultat de la s///. Merci encore!
Dom Hastings

OK, tu es le plus petit.
marinus

1
Ce n'est plus la réponse la plus courte.
geocar

6

Powershell, 131 126 121 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){...} - mettre l'accumulateur à 0 et boucler pour toujours
  • read-host '>>' - obtenir l'entrée utilisateur avec invite >>
  • [char[]](...) - convertir l'entrée utilisateur en un tableau de caractères
  • |%{...} - effectuer ce qu'il y a à l'intérieur {}pour chaque personnage
  • switch -r($_) - commutateur regex pour chaque personnage
  • "i|x"{$x++} - correspondre iou x- augmenter l'accumulateur
  • "d"{$x-=!!$x} - match d- diminue $xde !!$x, qui sera 0si $xest 0, et 1sinon. Cela garantit que l'accumulateur n'atteint jamais -1.
  • "s|k"{$x*=$x} - match sou k- carré
  • "o|c"{$x} - correspondre oou c- sortir l'accumulateur
  • $x*=$x-ne256- multiplier l'accumulateur par 0s'il l'est 256ou par le 1contraire

Exemple de sortie

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

Je suppose que l'implémentation de read-hostest spécifique à l'hôte, donc cet hôte Powershell (ConsoleHost) s'ajoute :à l'invite spécifiée.


Agréable! J'adore la décrémentation !!$x, dommage que je ne puisse pas utiliser ça ...
Dom Hastings

Hé Danko, pourriez-vous publier des résultats de test s'il vous plaît? Je ne pense pas pouvoir tester Power Shell sur des non-fenêtres ... (veuillez me corriger si je me trompe!)
Dom Hastings

J'ai ajouté une sortie de test à la réponse.
Danko Durbić

6

Rebol 3, 178 169 161 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]

Version plus jolie:

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

Vous pourriez probablement enregistrer quelques caractères en changeant eet ven opérateurs. J'ai également essayé de réécrire vet gpour que le paramètre xreste en IO, printetc. Je n'ai pas réussi à le faire fonctionner, mais je pense que ce pourrait être un bon endroit où aller pour quelqu'un qui connaît son haskell.
shiona

@shiona: Ouais, le fait de garder les choses IOest qu'elles impriment trop souvent (c'est pourquoi j'ai utilisé à la r nplace de x) ou pas assez parce que la valeur n'est jamais demandée…. Alors, comment pourrais-je changer eet vdevenir opérateur?
Ry-

J'ai eu les mêmes problèmes d'impression. Ce qui vient aux opérateurs que vous pouvez faire (en utilisant e comme exemple) 'i'%x=x+1;'d'%x=x-1... Et appelez-le simplement dans v do n<-x;r$w$o%n. La raison pour laquelle les opérateurs économisent de l'espace est qu'ils n'ont pas besoin d'espace autour d'eux.
shiona

@shiona: Oh! Bon appel, merci!
Ry-

Aucun problème. J'ai d'abord pensé à faire ma propre réponse, mais comme je ne pouvais pas faire fonctionner mes grandes idées, je pensais que ce serait juste impoli de publier exactement le même code avec une notation juste différente pour les mêmes fonctions.
shiona

4

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

Exemple de session (identique à la vôtre):

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

Ma version est plus courte. J'ai compressé la carte, compté sur ? pour classer les valeurs "d'habillage", a utilisé la récursivité au lieu de while, et un interpréteur fonctionnel au lieu de modifier.
geocar

4

Ada

Voici une implémentation Ada pour les quelques personnes intéressées par ce langage. Il m'a fallu un certain temps pour utiliser certaines des meilleures pratiques d'Ada (comme l'utilisation d'Indefinite_Holders au lieu de l'accès) et aussi pour comprendre pleinement comment doit fonctionner 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;

Et la sortie:

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

Si certaines personnes expérimentées à Ada pouvaient me donner quelques conseils d'optimisation, je serais reconnaissant.


1
Bienvenue chez PPCG! Le but de code-golf est de créer le code le plus court possible, et vous devez inclure la taille de votre programme dans l'en-tête (1396 octets ici)
TuxCrafting

4

C, 159 caractères

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

J'ai essayé une autre approche basée sur la mise en place d'une table de recherche pour le décodage des instructions, mais malheureusement, cela s'est avéré plus long ( 169 ). Je l'ai inclus car quelqu'un pourrait proposer un ajustement intelligent pour réduire la taille. (Doit être exécuté sans aucun argument)

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

Cela produit une nouvelle ligne après le >>, mais l'OP n'a pas dit que ce n'était pas autorisé. Plus maintenant!

Merci à GlitchMr, minitechet golfer9338!


1
Vous pouvez utiliser lambdaau lieu de defpour une fonction qui renvoie immédiatement.
Konrad Borowski

x in(-1,256)enregistre deux caractères. Alternativement, s=lambda x:"a=%d"%(x!=-1and x!=256and x)pourrait en sauver quelques-uns.
Ry-

1
Vous pouvez supprimer print(">>")et utiliser à la for i in input(">>")place; input()permet de spécifier une invite. Ensuite, il n'y aura plus de nouvelle ligne >>et vous enregistrerez des caractères.
golfer9338

Votre score devrait être, je pense, un caractère plus court en ce moment. Veuillez vérifier à nouveau, mais j'obtiens un nombre de 161 au lieu des 162 affichés: lignes de 3 + 40 + 8 + 107, plus 3 nouvelles lignes. À vrai dire, je suis jaloux, car de toute façon, vous êtes quelques caractères plus courts que ma réponse C. À votre santé!
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")}}

Version non golfée:

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

Exemple de session (en mode interactif):

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

Je sais que je suis en retard, mais je voulais profiter de l'occasion pour publier une version Python plus courte (et ma première tentative 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 déclaration d'impression était un peu délicate pour cela. Si l'invite doit se terminer par un espace, ajoutez un caractère au nombre. :)

Explication

v est l'accumulateur.

mvérifie si la valeur donnée est -1ou 256. Si c'est le cas, 0sera retourné, la valeur sinon.

Dans les lignes suivantes, les opérations sont affectées aux variables correspondantes (car certaines ont la même signification (comme iet x) c'est plus court que l'instanciation d'un nouveau dictionnaire). Ceux-ci sont ensuite utilisés dans ce qui execsuit.

while 1: est la boucle principale

Maintenant, le plaisir commence. Comme la solution de @jazzpi , elle itère sur chaque caractère de l'entrée. locals()est le dictionnaire de toutes les variables actuelles (visibles). Avec .get(n,'')la clé correspondante sera mise dans la chaîne exec (une chaîne vide, si la clé (= autre entrée) n'a pas été trouvée). Celui-ci sera alors, une fois exécuté, concaténé vet transmis vers m. La valeur de retour sera à vnouveau enregistrée .

Petit exemple:

Be n = 'i'( n= input-char), on '+1'sort du locals-block comme l' iest la variable avec value '+1'.
La chaîne des execque se présente comme suit: 'v=m(v+1)'.
Peut-être que maintenant il est plus facile de voir que, lors de l'exécution, il appellera mavec la valeur de v+1et stockera à vnouveau sa sortie .

Répétez cette opération jusqu'à ce que vous vous ennuyiez. :)


Je me rends compte que je suis TRÈS en retard à la fête, mais le lambda pour m peut être y*(-1!=y!=256)de -3 octets
Rétablir Monica le

seulement 5 ans :) merci pour la contribution cependant. Je suis trop paresseux pour fixer la réponse, mais je vais m'en souvenir
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

C'est bien, mais aussi assez simple. Voici une version plus longue et plus cool:

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)

Pesant 190 caractères, ce n'est peut-être pas la réponse la plus compétitive ici. D'un autre côté, les coroutines sont plutôt cool et je cherche toujours une excuse pour les utiliser (et les partager)


3

TI-BASIC, 104 107 102 100 98

Pour les calculatrices de la série TI-83 + / 84 +.

Nommez ceci prgmD; il déborde finalement la pile en s'appelant. Remplacez la récursivité par un While 1, au prix de deux octets, pour résoudre ce problème.

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 est 0 par défaut, donc exécutez-le avec une calculatrice fraîchement effacée de la mémoire ou stockez 0 à Y manuellement avant de l'exécuter.

Dommage que les lettres minuscules (dans les littéraux de chaîne) soient deux octets chacune; sinon, ce serait plus court que la réponse de Dom Hastings.

EDIT: correction d'une erreur de division par zéro (0 ^ 0) au prix de trois octets.

107 -> 102: Astuce d'exponentiation imaginaire pour enregistrer quatre octets (dont 1 entre parenthèses et -1 pour allonger la chaîne de recherche) et utilisé Y au lieu de X, ce qui prend un octet de moins à initialiser.


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

Non golfé:

/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 caractères)

C'est probablement un mauvais choix de langue, mais bon. Ce n'est pas qu'un langage comme C peut faire mieux qu'un langage de programmation dynamique. Sur Clang, vous devrez spécifier une valeur pour return(ce n'est pas nécessaire pour 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();}}

Ne serait-il pas plus court de supprimer define qet d'utiliser simplement printf?
Poignée de porte

@DoorknobofSnow En fait non. qest utilisé 3 fois, define qéconomise donc environ 2 caractères.
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 _

Pas le pire, pas le meilleur.

REMARQUE: tel que rapporté par @mniip 256or peut ne pas fonctionner dans votre interprète. Plus d'infos dans les commentaires.

(plus ou moins) Version lisible:

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 _

Sortie:

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

Edit: merci à @mniip pour l'optimisation 2 caractères: until nil->until _


repeat until x(x est nul car non défini) est de 2 caractères plus court, et a while 1 do endexactement la même longueur, à part cela quelle version lua est-ce? 256orest une syntaxe non valide dans mon interprète
mniip

@mniip Merci pour un indice repeat until x. J'utilise le dernier binaire Windows d' ici . Comme vous pouvez le voir, vous a=a+1 elseifavez de l'espace. C'est parce que ec'est un chiffre hexadécimal, tandis que odans 256orn'est pas, donc mon interprète prend orcomme une autre instruction / block / howYouCallIt.
Egor305

ouais à peu près d'ailleurs 256or, aussi 0repeatet 1then; J'utilise lua officiel de lua.org, votre code ne compile pas en 5.1, 5.2 ou 5.3
mniip

2

Haskell , 186 178 octets

Ce doit être exécuté avec runhaskell(ou à l' intérieur ghci) , car ils établissent les conditions BufferModeà NoBufferingpar défaut qui coffres - forts beaucoup d'octets:

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

Essayez-le en ligne!

Explication

Ceci définit un nouvel opérateur state # source(la déclaration de fixité nous permet de tomber entre parenthèses lorsque vous l' utilisez conjointement avec d' autres opérateurs (+), (-), (^), (:)et (>>)):

  • les deux premières lignes "fixent" les états -1et256
  • il correspond alors au premier caractère et agit sur lui
  • une fois qu'il manque de caractères ( r#_), il en lit de nouveaux et recommence en conservant l'ancien état

Pour démarrer le processus, nous initialisons l'état avec 0et lisons une nouvelle ligne source, c'est-à-dire. commencer par une source vide:

main=0#""

1

Lot 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

Ignore avec succès les autres commandes. Vraiment gonflé sans avoir orà travailler avec ...

Modifier:

Fixé:

  • Fini l'écho de toutes les commandes
  • Je l'ai fait faire des maths avec / a
  • Réinitialiser sur -1
  • Réinitialiser l'entrée après chaque cycle

Cela a coûté 52 caractères.

N'a pas corrigé:

  • La mise au carré 0 écrit "0 * 0" dans a.
  • L'entrée d'espace (ou rien, lorsque vous venez de l'ouvrir) plante le script.
  • Vous DEVEZ entrer un caractère à la fois.

2
Celui-ci ne fonctionne tout simplement pas du tout (Windows 7). Je ne veux pas être un connard, mais avez-vous testé cela?
marinus

@marinus Il a été corrigé.
Timtech

1

Script de commande Windows - 154

Abusin fonctionnalités inconnues au maximum.

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

J'ai fait une autre réponse> <> car je n'ai pas pu tester les phases et il a utilisé des commandes pré-empilées plutôt que d'émuler un shell de toute façon.

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

Il peut certainement être joué au golf, mais je ne suis pas sûr d'avoir la bravoure de la folie nécessaire !

Je l'ai testé avec l'interpréteur officiel fonctionnant sous python 3.5 sous cygwin sous windows 7 et j'ai pu reproduire le 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

Dans le cas où vous ne pouvez pas l'exécuter sur votre machine (la saisie semble difficile) ou si vous souhaitez simplement l'essayer sans aucun autre logiciel, vous pouvez utiliser la version suivante sur l' interpréteur en ligne .

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

Il ignore évidemment \ n et EOF car vous ne pouvez pas les entrer dans l'interpréteur en ligne, mais se comportera comme si enter avait été enfoncé après chaque commande de sortie.


1

C (gcc) , 139 octets

Compilez avec -Dk="_nZZiaeY"(inclus dans le nombre d'octets). -2 octets si l'invite >>\nest autorisée.

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

Essayez-le en ligne!

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

Si seulement je pouvais me débarrasser de cet hFlush stdoutappel embêtant ! Sans cela, l'invite ne s'affiche pas tant qu'une oopération n'est pas effectuée. Aucun conseil?


Vous pouvez vous débarrasser de hFlushen utilisant runhaskellau lieu de compiler (voir ma réponse ), mais quant à cette solution, elle n'est pas valide et les erreurs sont éliminées.
ბიმო

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>

la sortie est un peu sommaire (l'historique / la session est affiché sur une zone de texte, et avec le rapport d'erreurs activé, de nombreux avertissements sont imprimés) mais tout fonctionne


0

> <>, 239

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

La pile initiale est l'entrée. Vous pouvez l'essayer en ligne ici .


0

Golf-Basic 84, 88 caractères

: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

Invite une commande à la fois, comme dans au moins 3 autres solutions. Voici un test pour xiskisc:

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

Également, xisksorenvoie 0, comme il se doit.


Quelles autres solutions demandent une commande à la fois?
Ry-

1
J'ai écrit celui de Haskell, et non, ce n'est pas le cas. Pas plus que Perl, donc je ne sais vraiment pas de quoi vous parlez.
Ry-

1
Cela ne suit pas les règles d'E / S.
marinus

1
Ne suit toujours pas les règles et utilise des lettres majuscules plutôt que des minuscules.
lirtosiast

1
Si vous connaissez TI-BASIC, il ne prend en charge que les majuscules.
Timtech

0

JavaScript (Node.js), 204 octets

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)

Cela peut probablement être joué au golf. Node.js prouve encore une fois que c'est une étrange verbosité déguisée. Code expliqué:

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 octets

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

serait de 283 octets si les utilisations et la déclaration de classe, etc. pouvaient être supprimées en fournissant simplement une définition de fonction

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.