Interprète de golf simple


13

Défi:

Votre travail consiste à créer un simple interprète pour une langue de golf simple.


Contribution:

L'entrée sera sous la forme d'une chaîne séparée par des espaces.

Vous pouvez remplacer la séparation d'espace par ce que vous voulez


Production:

Affiche le résultat (un nombre ou une chaîne) obtenu après avoir effectué toutes les opérations. S'il y a plus d'une sortie, joignez-les ensemble pour donner un seul résultat (pas de séparateurs). La valeur initiale de la variable est toujours nulle. c'est à dire: ça commence à0


Syntaxe de la langue:

La langue a les opérateurs suivants:

inc  ---> add one to variable
dec  ---> remove one from variable
mult ---> multiply variable by 2
half ---> divide the variable by 2
Pri  ---> print the variable to console (or whatever your language has)
exit ---> end the program (anything after this is ignored)

Exemples:

inc inc inc dec Pri exit                 ---> 2
dec inc mult inc inc Pri                 ---> 2
inc inc inc mult half Pri exit inc       ---> 3
inc Pri inc Pri inc Pri exit half mult   ---> 123
Pri exit                                 ---> 0
inc half Pri exit                        ---> 0.5 

Restriction:

Il s'agit de code-golf, donc le code le plus court en octets pour chaque langue gagnera.


Remarque:

  • L'entrée sera toujours valide. (chaîne d'opérateurs séparés par un espace)
  • Vous pouvez arrondir à l'entier le plus proche si vous ne voulez pas de décimales.

3
Puis-je prendre une liste de chaînes? Puis-je utiliser une autre capitalisation?
user202729

Ajouter un cas de sortie? la sortie devrait avoir de l'importance
l4m2 le

1
@Kaldo: Vous pouvez vous séparer en utilisant de nouvelles lignes
Muhammad Salman

3
Hmm, je n'appellerais pas cette langue "langue de golf".
Paŭlo Ebermann

1
Il s'agit de Deadfish avec un double et demi au lieu de noms de commandes carrés et plus longs
Jo King

Réponses:


8

Bash , 61 octets

sed '1i0
s/.//2g;y"idmhe"+-*/q";/+\|-/i1
/*\|\//i2
/P/cdn'|dc

Essayez-le en ligne!

Convertit le programme en programme DC, puis l'évalue en tant que code DC. Cela prend l'entrée séparée par des retours à la ligne. Notez que dc est basé sur la pile et utilise la notation de polissage inversé.

L'entrée est d'abord dirigée vers sed

1i0 sur la première ligne d'entrée, insérez (ajoutez) un 0, ce sera l'accumulateur

s/.//2g supprimer tout sauf le premier caractère de chaque ligne

y"idmhe"+-*/q"translittérer idmheen+-*/q respectivement + - * / sont les commandes arithmétiques et q quitte le programme

/+\|-/ sur chaque ligne contenant + ou -, i1 insérez un 1

/*\|\// sur chaque ligne contenant * ou /, i2 insérez un 2

/P/ sur chaque ligne contenant P, cdn changez-le en dn, équivalent à dupliquer et sortez sans nouvelle ligne en dc

Maintenant, cela est évalué comme une expression cc.


2
Je suppose qu'il n'est pas déraisonnable de s'attendre à ce que la sedsyntaxe devienne encore plus étrangère que ce que l'on pensait possible lorsque le golf entre en jeu.
Mateen Ulhaq

6

Gelée , 21 octets

ḲḢ€O%11ị⁾’‘j“IȮḤH”¤VI

Essayez-le en ligne!


Notez que les valeurs ASCII des premiers caractères ( idmhPe) modulo 11 sont uniques modulo 6.


Utilisation de modulo 16:

Gelée , 21 octets

ḲḢ€O%⁴ị“ḢwġḞkz’ṃØJ¤VI

Essayez-le en ligne!

La chaîne utilisée pour l'indexation est ḤH‘’IȮdans ce cas. Ils ‘’ne sont plus aux frontières.


Utiliser 11 octets pour représenter une chaîne de 6 octets est ... dommage. Mais ... “”prend 2 octets, ¤prend 1 octet, les données elles-mêmes prennent 6 octets, il reste 2 octets pour faire quelque chose. Actuellement, c'est et j, mais ịØJou ṃØJest bien pire, et ne fonctionne pas (car Unicode).
user202729

Le concept de chaîne de jli ("Une chaîne est une liste d'entiers avec un drapeau spécial pour affecter l'impression") est excellent.
user202729

5

R , 128 125 octets

Reduce(function(x,y)switch(y,i=x+1,d=x-1,m=x*2,h=x/2,P={cat(x);x}),substr(el(strsplit(gsub("e.*$","",scan(,""))," ")),1,1),0)

Essayez-le en ligne!

Doit être appelé avec source(echo=FALSE)pour empêcher l'impression automatique de la valeur de retour. L'alternative serait de tout envelopperinvisible mais c'est beaucoup moins golfique (et ruine mon [encore] joli nombre d'octets).


3

05AB1E , 25 octets

΀¬"idmhPe"S"><·;=q"S‡J.V

Essayez-le en ligne!

Mappe chacune des fonctions de langage avec la fonction 05AB1E correspondante (en utilisant le premier caractère de chaque fonction), puis exécute la chaîne résultante en tant que code 05AB1E.


2

Rouge , 121 octets

func[s][v: 0 parse s[any[["i"(v: v + 1)|"d"(v: v - 1)|"m"(v: v * 2)|"h"(v: v / 2.0)|"P"(prin v)|"e"(exit)]thru" "| end]]]

Essayez-le en ligne!

Lisible:

f: func [s] [
    v: 0
    parse s [
        any [
            [ "i" (v: v + 1)
            | "d" (v: v - 1)
            | "m" (v: v * 2)
            | "h" (v: v / 2.0)
            | "P" (prin v)
            | "e" (exit)]
            thru [" " | end]
        ]
    ]
] 

2

Python 2 , 131 125 122 121 118 118 117 115 octets

v=0;o=""
for x in input().split("x")[0].split():
 if"Q">x:o+=`v`
 else:v+=(1,-1,v,-v/2.)['idmh'.find(x[0])]
print o

Essayez-le en ligne!

-6 et -3 avec merci à @Rod

-3 et -2 avec merci à @etene

-1 en remplaçant "Pri"==xpar"P"in x


vous pouvez splitsur "exit"et obtenir le 1er bloc, au lieu breaking sauver 4 octets
Rod

1
Vous pouvez supprimer les parenthèses autour 'idmh'et utiliser à la findplace de index, cela économisera quelques octets
etene

@Rod - peut en fait aller un peu plus loin et se séparer expour en sauver 2 autres
ElPedro

Vous pouvez remplacer v=(v+1,v-1,v*2,v/2.)avec v+=(1,-1,v,-v/2.)cela devrait fonctionner, mais n'a pas été testé
Rod

@Rod - y a réfléchi mais n'a pas pu trouver comment faire half . Si simple! Merci.
ElPedro

2

Python 3 , 110 91 82 octets

exit entraînera la fermeture du programme avec une erreur.

x=0
for c in input():c=='P'==print(x,end='');x+=(1,-1,x,-x/2,c,0)['ndmhx'.find(c)]

Essayez-le en ligne!


Raccourcissez vos noms de variables pour économiser 9 octets. i='x+=1';d='x-=1';...puis dans votre execappel, changez-le enexec(eval(c[0]))
mypetlion

@mypetlion Merci, mais j'ai trouvé un meilleur moyen.
mbomb007

Je pense que cela est valide: 82 octets
Lynn

@Lynn C'est super! Je ne pouvais pas penser à une belle façon de court-circuiter la printdéclaration!
mbomb007

2

JavaScript (ES6), 83 79 octets

4 octets enregistrés grâce à @ l4m2

Remplace itérativement les instructions par la sortie ou des chaînes vides.

s=>s.replace(/\S+./g,w=>m<s?'':w<{}?m:(m+={d:-1,e:w,i:1,m}[w[0]]||-m/2,''),m=0)

Essayez-le en ligne!

Commenté

s =>                       // given the input string s
  s.replace(/\S+./g, w =>  // for each word w in s:
    m < s ?                //   if m is a string:
      ''                   //     ignore this instruction
    :                      //   else:
      w < {} ?             //     if w is 'Pri' ({} is coerced to '[object Object]'):
        m                  //       output the current value of m
      : (                  //     else:
          m +=             //       add to m:
            { d: -1,       //         -1 if w is 'dec'
              e: w,        //         w  if w is 'exit' (which turns m into a string)
              i: 1,        //         1  if w is 'inc'
              m            //         m  if w is 'mult'
            }[w[0]]        //       using the first character of w to decide
            || -m / 2,     //       or add -m/2 (for 'half') if the above result was falsy
        ''),               //       do not output anything
    m = 0                  //   m = unique register of our mighty CPU, initialized to 0
  )                        // end of replace()

s=>s.replace(/\S+./g,w=>k<s?'':w<{}?k:(k+={d:-1,e:w,i:1,m:k}[w[0]]||-k/2,''),k=0)
l4m2 le

@ l4m2 C'est w<{}du mal pur: p
Arnauld

s=>s.replace(/\S+./g,e=>m<s?'':e<{}?m:(m+={d:-1,e,i:1,m}[e[0]]||-m/2,''),m=0)fonctionnent également
l4m2 le

2

Fusain , 37 35 octets

≔⁰ηF⎇№θx…θ⌕θxθ≡ιn≦⊕ηd≦⊖ηm≦⊗ηh≦⊘ηrIη

Essayez-le en ligne! Le lien est vers la version détaillée du code. Inspiré par la réponse de @ RickHitchcock. Explication:

≔⁰η

Effacez la variable.

F⎇№θx…θ⌕θxθ≡ι

Tronquez l'entrée à xs'il y en a une, puis bouclez et activez chaque caractère (le reste de) l'entrée.

n≦⊕η

ni n incrémente la variable.

d≦⊖η

d d ecrements la variable.

m≦⊗η

m m ultiplies la variable par deux ( par exemple double).

h≦⊘η

h h alves la variable.

rIη

rp r entre la variable transtypée en chaîne.


1
@RickHitchcock Désolé, je n'ai pas testé cela de manière suffisamment approfondie. J'ai trouvé une solution de contournement mais cela m'a coûté un octet.
Neil

2

JavaScript (ES6), 77 75 octets

(Emprunté ( volé ) @ Astuce d'Arnauld d'utiliser mcomme nom de variable, économisant 2 octets.)

f=([c,...s],m=0)=>c<'x'?(c=='P'?m:'')+f(s,m+({h:-m/2,d:-1,n:1,m}[c]||0)):''

Parcourt récursivement la chaîne, recherchant des lettres distinctes par instruction et ignorant le reste:

  • n: inc
  • d: dec
  • m: mult
  • h: moitié
  • P: Pri
  • x: quitter

Profite du fait qu'il undefinedn'est ni supérieur ni inférieur à 'x', provoquant l'arrêt de la récursivité à la fin de la chaîne ou lorsqu'elle rencontre la sortie'x' in .


1
Suite à votre commentaire supprimé auquel je ne peux bien sûr plus répondre, j'ai oublié de coller le lien vers le code corrigé (d'oh!) Mais j'ai trouvé une nouvelle approche qui est de 2 octets plus courte que ma tentative d'origine de toute façon.
Neil



1

JavaScript, 107 octets

s=>eval('x=0;x'+(s.split` `.map(v=>({i:"++",d:"--",m:"*=2",h:"/=2",P:";alert(x)",e:"//"})[v[0]]).join`;x`))


1

Lua, 207 octets

s=0;n=0;for a in io.read():gmatch'.'do if s==0 then s=1;n=a=='i'and n+1 or a=='d'and n-1 or a=='m'and n*2 or a=='h'and n/2 or n;if a=='P'then print(n)elseif a=="e"then break end elseif a==' 'then s=0 end end

1

Python 3 , 114 110 109 116 116 octets

En fait, aurait pris deux octets de moins en Python 2 car execc'est une instruction et n'a pas besoin de parenthèses ...

  • 4 octets supplémentaires enregistrés grâce à @ElPedro

  • Sauvegarde d'un octet supplémentaire en profitant du fait que findrenvoie -1 en cas d'erreur, qui peut ensuite être utilisé comme index

  • +7 octets car je n'avais pas remarqué la règle de non-retour à la ligne :(

i=0;exec(";".join("i+=1 i-=1 i*=2 i/=2 print(i,end='') exit()".split()["idmhP".find(h[0])]for h in input().split()))

Essayez-le en ligne!

Mappe le premier caractère de chaque mot saisi à un morceau de code Python. Celles-ci sont ensuite concaténées et execéditées.

Approche assez simple, qui pourrait probablement être un peu plus jouée au golf. La difficulté réside principalement dans la recherche de la forme la plus courte parmi les nombreuses possibles ...


112 Essayez-le en ligne! si vous avez les commandes comme une chaîne séparée par des espaces et que vous les divisez.
ElPedro

1
110 en fait comme les crochets peuvent aller Essayez-le en ligne!
ElPedro

Cela ne donne pas la sortie correcte. La question dit que vous devez imprimer sans séparateurs, donc vous en avez besoin print(i,end=''). Voir le 4ème cas de test.
mbomb007

Je ne l'avais pas remarqué, je vais le réparer. Merci !
etene

@etene Commentez quand vous l'avez corrigé et je vais supprimer mon downvote.
mbomb007

1

Ruby + -na, 81 73 65 octets

x=0;$F.map{|w|eval %w{x+=1 x-=1 1/0 $><<x x*=2 x/=2}[w.ord%11%6]}

Essayez-le en ligne!

Assez simple. Pour la première lettre de chaque mot, recherchez la chaîne de commande correspondante et evalcelle - ci. Utilise la division entière et exitsen lançant a ZeroDivisionError.

-5 octets: utilisez .ord%11%6au lieu d'une recherche de chaîne. Le crédit revient à user202729

-3 octets: .ordne prend en compte que le premier caractère de la chaîne, je peux donc ignorer a [0].

-8 octets: utilisez l' -aindicateur pour diviser automatiquement les entrées, grâce à Kirill L.


1
Vous pouvez économiser encore plus d'octets en ajoutant une -aoption pour faire l'autosplit pour vous, comme ceci
Kirill L.

1

Emojicode , 270 octets

🐖🔥🍇🍮c 0🔂j🍡💣🐕🔟 🍇🍊😛j🔤inc🔤🍇🍮c➕c 1🍉🍋😛j🔤dec🔤🍇🍮c➖c 1🍉🍋😛j🔤mult🔤🍇🍮c✖️c 2🍉🍋😛j🔤half🔤🍇🍮c➗c 2🍉🍋😛j🔤Pri🔤🍇👄🔡c 10🍉🍓🍇🍎🍉🍉🍉

Essayez-le en ligne!

🐋🔡🍇
🐖🔥🍇
🍮c 0
🔂j🍡💣🐕🔟 🍇
🍊😛j🔤inc🔤🍇🍮c➕c 1🍉
🍋😛j🔤dec🔤🍇🍮c➖c 1🍉
🍋😛j🔤mult🔤🍇🍮c✖️c 2🍉
🍋😛j🔤half🔤🍇🍮c➗c 2🍉
🍋😛j🔤Pri🔤🍇👄🔡c 10🍉
🍓🍇🍎🍉🍉🍉🍉

🏁🍇
 🔥🔤inc inc inc dec Pri exit🔤
😀🔤🔤
 🔥🔤dec inc mult inc inc Pri🔤
😀🔤🔤
 🔥🔤inc inc inc mult half Pri exit inc🔤
😀🔤🔤
 🔥🔤inc Pri inc Pri inc Pri exit half mult🔤
😀🔤🔤
 🔥🔤Pri exit🔤
😀🔤🔤
 🔥🔤inc half Pri exit🔤
🍉

0

SNOBOL4 (CSNOBOL4) , 165 octets

	P =INPUT ' exit ' 
	x =0
S	P LEN(1) $ L ARB ' ' REM . P	:S($L)F(end)
i	X =X + 1	:(S)
d	X =X - 1	:(S)
P	O =O X		:(S)
m	X =X * 2	:(S)
h	X =X / 2.	:(S)
e	OUTPUT =O
END

Essayez-le en ligne!

Brut.

	P =INPUT ' exit ' 				;* append ' exit ' to the input to guarantee that the program will stop
	x =0						;* initialize x to 0 else it won't print properly if the program is 'Pri'
S	P LEN(1) $ L ARB ' ' REM . P	:S($L)F(end)	;* set L to the first letter of the word and goto the appropriate label
i	X =X + 1	:(S)
d	X =X - 1	:(S)
P	O =O X		:(S)				;* append X to the output string
m	X =X * 2	:(S)
h	X =X / 2.	:(S)				;* divide by 2. to ensure floating point
e	OUTPUT =O					;* print whatever's in O, which starts off as ''
END

0

C # (.NET Core), 186 octets

class P{static void Main(string[]a){int v=0;foreach(var s in a){var i=s[0];if(i=='i')v++;if(i=='d')v--;if(i=='m')v*=2;if(i=='h')v/=2;if(i=='P')System.Console.Write(v);if(i=='e')break;}}}

Vous pouvez réduire de 26 octets cela en faisant quelques choses simples, comme déclarer iavec v, consulter une table ASCII pour pouvoir utiliser des petits nombres, réorganiser les ifs, puis utiliser un ternaire: class Z{static void Main(string[]a){int v=0,i;foreach(var s in a){i=s[0]%'d';if(i==1)break;if(i>9)System.Console.Write(v);else v=i<1?v-1:i<5?v/2:i<6?v+1:v*2;}}}(PS une explication de la façon dont cela fonctionne et comment utiliser il (par exemple s'attend à des arguments de ligne de commande) est toujours apprécié!)
VisualMelon

(Oh, c'est gênant ... j'aurais dû utiliser à la %50place de %'d')
VisualMelon

0

Perl 5 -a , 61 octets

eval'$,'.qw(++ -- ;exit ;print$,||0 *=2 /=2)[(ord)%11%6]for@F

Essayez-le en ligne!

A volé @ user202729 ord%11%6 astuce

Comment?

-a            # split the input by whitespace, store in @F
eval          # Execute the string that results from:
'$,'          # $, (the accumulator)
.             # appending:
qw(           # create an array for the following whitespace separated values:
++ --            # operators for inc & dec
;exit            # exit
;print$,||0      # Pri  (||0 ensures that 0 is output if accumulator is null
*=2 /=2)         # mult div
[(ord)%11%6] # @user202729's trick selects one of the preceding operations
for@F        # for every term input

0

Pyth, 44 Bytes

Vmx"idmhPe"hdcwd=Z@[hZtZyZcZ2ZZ)NIqN4pZIqN6B

Test Suite

explanation

Vmx"idmhPe"hdcwd=Z@[hZtZyZcZ2ZZ)NIqN4pZIqN6B   ## full program
             cwd                               ## split input on space
Vmx"idmhPe"hd                                  ## iterate through list of numbers corresponding to operators
                =Z@[hZtZyZcZ2ZZ)N              ## assign the variable Z (initialliy Zero) it's new value
                                 IqN4pZ        ## print Z if the current operator is "Pri" (4)
                                       IqN6B   ## break if the current operator is "exit" (5)

0

TI-BASIC, 112 bytes

This takes advantage of some assumptions that are AFAIK perfectly acceptable. Number one being that all variables are initialized to zero prior to execution; number two being that input is taken via Ans.

Ans+" E→Str1
While 1
I+4→I
sub(Str1,I-3,1→Str2
A+(Ans="I")-(Ans="D
If inString("MH",Str2
Then
I+1→I
2AAns+A/2(1-Ans
End
If Str2="P
Disp A
If Str2="E
Stop
Ans→A
End

0

Java (OpenJDK 8) , 164 octets

a->{int c=0;for(String g:a.split(" ")){char b=g.charAt(0);if(b==105)c++;if(b==100)c--;if(b==109)c*=2;if(b==104)c/=2;if(b==80)System.out.print(c);if(b==101)return;}}

Essayez-le en ligne!

Ci-dessus est ma solution qui arrondit aux nombres entiers, mais ci-dessous est ma solution qui gère les décimales. La façon odieuse dont les impressions java doublent ajoute 55 byes supplémentaires au score. J'ai laissé les nouvelles lignes pour rendre le code plus lisible dans la deuxième soumission uniquement parce que c'est essentiellement la même solution avec une commande supplémentaire et une instruction d'importation.

Java (OpenJDK 8) , 219 octets

a->{
double c=0;
for(String g:a.split(" ")){
char b=g.charAt(0);
if(b==105)c++;
if(b==100)c--;
if(b==109)c*=2;
if(b==104)c/=2;
if(b==80)System.out.print(new DecimalFormat("0.#").format(c));
if(b==101)return;}}

Essayez-le en ligne!


0

C (gcc) , 120 114 111 bytes

-6 octets grâce au plafond.

x,d;f(char*s){for(x=0;s>1;s=index(d^1?s:"",32)+1)d=*s-100,x+=d?d==5:-1,x*=d^9?d^4?1:.5:2,d+20||printf("%d",x);}

Essayez-le en ligne!

124 octets

Version à virgule flottante:

d;f(char*s){for(float f=0;s>1;s=strchr(s,32)+1)d=*s-80,f+=d==25,f-=d==20,f*=d^29?d^24?1:.5:2,s=d^21?s:"",d?:printf("%f",f);}

Essayez-le en ligne!

Je n'ai pas pris la peine d'une version qui arrondit, mais fait une exception pour 0, ce qui serait autorisé, si je comprends bien la chaîne de commentaires.


0

33, 62 bytes

s'i'{1a}'d'{1m}'m'{2x}'h'{2d}'P'{o}'e'{@}It[mzsjk""ltqztItn1a]

Try it online!

This program takes the instructions delimited by newlines

Explanation:

It[mzsjk""ltqztItn1a]
  [mz            n1a] | Forever
It    jk       It     | - Get the first character of the next instruction
            qz        | - Call the function declared previously
     s  ""lt  t       | - Make sure we don't lose track of the variable

The code before that segment defines all the functions.

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.