Interprete di golf semplice


13

Sfida:

Il tuo compito è creare un semplice interprete per un semplice linguaggio da golf.


Ingresso:

L'input sarà in forma di stringa separata da spazi.

Puoi sostituire la separazione spaziale con ciò che desideri


Produzione:

Stampa il risultato (un numero o una stringa) ottenuto dopo aver eseguito tutte le operazioni. Se ci sono più di un output, unisci insieme per dare un singolo risultato (nessun separatore). Il valore iniziale della variabile è sempre zero. vale a dire: inizia alle0


Sintassi linguistica:

La lingua ha i seguenti operatori:

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)

Esempi:

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 

Restrizione:

Questo è code-golf, quindi vincerà il codice più breve in byte per ogni lingua.


Nota:

  • L'input sarà sempre valido. (stringa di operatori separati da spazio)
  • Puoi arrotondare per difetto all'intero più vicino se non vuoi i decimali.

3
Posso prendere un elenco di stringhe? Posso usare un'altra maiuscola?
user202729,

Aggiungi caso di uscita? l'uscita dovrebbe importare
l4m2

1
@Kaldo: puoi separare usando nuove linee
Muhammad Salman,

3
Hmm, non chiamerei quella lingua "lingua del golf".
Paŭlo Ebermann,

1
Questo è Deadfish con doppio e mezzo invece di nomi di comando quadrati e più lunghi
Jo King

Risposte:


8

Bash , 61 byte

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

Provalo online!

Converte il programma in un programma CC, quindi lo valuta come codice CC. Questo prende l'input separato da newline. Si noti che dc è basato su stack e utilizza la notazione polacca inversa.

L'ingresso viene prima reindirizzato a sed

1i0 sulla prima riga di input, inserire (anteporre) uno 0, questo sarà l'accumulatore

s/.//2g rimuovi tutto tranne il primo carattere su ogni riga

y"idmhe"+-*/q"traslitterare rispettivamente idmhein +-*/q+ - * / sono i comandi aritmetici e q esce dal programma

/+\|-/su ogni riga contenente + o -, i1inserire un 1

/*\|\//su ogni riga contenente * o /, i2inserire un 2

/P/su ogni riga contenente P, cdnmodificalo in dn, equivalente a duplicato e output senza newline in dc

Ora questo viene valutato come un'espressione cc.


2
Suppongo che non sia irragionevole aspettarsi che la sedsintassi diventi ancora più aliena di quanto si pensasse in precedenza quando si gioca a golf.
Mateen Ulhaq,

6

Gelatina , 21 byte

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

Provalo online!


Si noti che i valori ASCII dei primi caratteri ( idmhPe) modulo 11 sono univoci modulo 6.


Utilizzando il modulo 16:

Gelatina , 21 byte

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

Provalo online!

In ḤH‘’IȮquesto caso, la stringa utilizzata per indicizzare . Non ‘’sono più sui confini.


L'uso di 11 byte per rappresentare una stringa di 6 byte è ... troppo male. Ma ... “”richiede 2 byte, ¤richiede 1 byte, i dati stessi richiedono 6 byte, rimangono 2 byte per fare qualcosa. Attualmente è e j, ma ịØJo ṃØJè molto peggio, e non funziona (perché Unicode).
user202729,

Il concetto di stringa di jli ("Una stringa è un elenco di numeri interi con un flag speciale per influire sulla stampa") è eccezionale.
user202729,

5

R , 128 125 byte

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)

Provalo online!

Deve essere chiamato con source(echo=FALSE)per impedire la stampa automatica del valore restituito. L'alternativa sarebbe di avvolgere tutto,invisible ma è molto meno golfy (e rovina il mio [ancora] bel conteggio di byte).


3

05AB1E , 25 byte

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

Provalo online!

Esegue il mapping di ciascuna funzione della lingua con la funzione 05AB1E corrispondente (utilizzando il primo carattere di ciascuna funzione), quindi esegue la stringa risultante come codice 05AB1E.


2

Rosso , 121 byte

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

Provalo online!

Leggibile:

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 117 115 byte

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

Provalo online!

-6 e -3 grazie a @Rod

-3 e -2 grazie a @etene

-1 sostituendo "Pri"==xcon"P"in x


si può splitin "exit"e ottenere il 1 ° blocco, invece breaking risparmio di 4 byte
Rod

1
È possibile rimuovere le parentesi intorno 'idmh'e utilizzare al findposto di index, che salverà alcuni byte
etene

@Rod - in realtà può fare un po 'di più e separarsi exper salvare un altro 2
ElPedro

Puoi sostituirlo v=(v+1,v-1,v*2,v/2.)con v+=(1,-1,v,-v/2.)esso dovrebbe funzionare, ma non testato
Rod

@Rod - ci ho pensato ma non sono riuscito a capire come fare half. Così semplice! Grazie.
ElPedro,

2

Python 3 , 110 91 82 byte

exit causerà la chiusura del programma con un errore.

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

Provalo online!


Abbreviare i nomi delle variabili per salvare 9 byte. i='x+=1';d='x-=1';...e poi nella tua execchiamata, exec(eval(c[0]))
cambialo in

@mypetlion Grazie, ma ho trovato un modo migliore.
mbomb007,

Penso che questo sia valido: 82 byte
Lynn,

@Lynn È fantastico! Non riuscivo a pensare a un modo carino per mettere in corto circuito l' printaffermazione!
mbomb007,

2

JavaScript (ES6), 83 79 byte

Risparmiato 4 byte grazie a @ l4m2

Sostituisce in modo iterativo le istruzioni con l'output o con stringhe vuote.

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

Provalo online!

Commentate

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

@ l4m2 Questo w<{}è puro male: 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)funziona anche
l4m2

2

Carbone , 37 35 byte

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

Provalo online! Il collegamento è alla versione dettagliata del codice. Ispirato dalla risposta di @ RickHitchcock. Spiegazione:

≔⁰η

Cancella la variabile.

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

Troncare l'input nel xcaso ce ne sia uno, quindi passare in rassegna e accendere ogni carattere di (il resto di) dell'input.

n≦⊕η

ni n crements variabile.

d≦⊖η

d d ecrements variabile.

m≦⊗η

m m ultiplies la variabile da due (cioè doppie).

h≦⊘η

h h alves la variabile.

rIη

rp r INT il cast variabile stringa.


1
@RickHitchcock Siamo spiacenti, non ho testato abbastanza a fondo. Ho trovato una soluzione alternativa ma mi è costato un byte.
Neil,

2

JavaScript (ES6), 77 75 byte

(Preso in prestito ( rubato ) Il trucco di Arnauld di usare mcome nome della variabile, risparmiando 2 byte.)

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

Cammina ricorsivamente la stringa, cercando lettere distinte per istruzione e ignorando il resto:

  • n: inc
  • d: dec
  • m: mult
  • h: metà
  • P: Pri
  • x: esci

Sfrutta il fatto che undefinednon è né maggiore né minore di 'x', causando l'arresto della ricorsione alla fine della stringa o quando incontra l' uscita'x' in uscita .


1
In seguito al tuo commento eliminato a cui ovviamente non posso più rispondere, ho dimenticato di incollare il link al codice corretto (d'oh!) Ma ho trovato comunque un nuovo approccio che è di 2 byte più corto del mio tentativo originale.
Neil,



1

JavaScript, 107 byte

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 byte

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 byte

In realtà avrebbe preso due byte in meno in Python 2 perché execè un'istruzione e non ha bisogno di parentesi ...

  • Salvato 4 byte extra grazie a @ElPedro

  • Salvataggio di un byte aggiuntivo sfruttando il fatto che findrestituisce -1 in caso di errore, che può quindi essere utilizzato come indice

  • +7 byte perché non avevo notato la regola no-newlines :(

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

Provalo online!

Mappa il primo carattere di ogni parola di input su un pezzo di codice Python. Questi vengono poi concatenati ed execed.

Approccio piuttosto semplice, che probabilmente potrebbe essere giocato un po 'di più. La difficoltà risiede principalmente nel trovare la forma più breve tra molte possibili ...


112 Provalo online! se si dispone dei comandi come stringa separata dallo spazio e divisa.
ElPedro,

1
110 infatti mentre le parentesi possono andare Provalo online!
ElPedro,

Questo non dà l'output corretto. La domanda dice che è necessario stampare senza separatori, quindi è necessario print(i,end=''). Vedi il quarto caso di test.
mbomb007,

Non me ne ero accorto, lo aggiusterò. Grazie !
etene,

@etene Commenta quando l'hai risolto e rimuoverò il mio downvote.
mbomb007,

1

Rubino + -na, 81 73 65 byte

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

Provalo online!

Abbastanza diretto. Per la prima lettera di ogni parola, trova la stringa di comando corrispondente e evalessa. Usa la divisione intera e exitslanciando aZeroDivisionError .

-5 byte: utilizzare al .ord%11%6posto di una ricerca di stringhe. Il merito va a all'utente202729

-3 byte: .ordconsidera solo il primo carattere della stringa, quindi posso saltare a[0] .

-8 byte: utilizzare -a flag per dividere automaticamente l'input, grazie a Kirill L.


1
Puoi salvare ancora più byte aggiungendo l' -aopzione per eseguire lo spaccatura automatica per te, in questo modo
Kirill L.

1

Emojicode , 270 byte

🐖🔥🍇🍮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🍉🍓🍇🍎🍉🍉🍉

Provalo online!

🐋🔡🍇
🐖🔥🍇
🍮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 byte

	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

Provalo online!

Schifoso.

	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 byte

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

È possibile radere 26bytes off questo facendo alcune cose semplici, come dichiarare icon v, consultando una tabella ASCII in modo da poter usare piccoli numeri, riordinando la ifs, e quindi utilizzando un ternario: 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 una spiegazione di come funziona e come si usa (ad es. si aspetta che la riga di comando si discuti) è sempre apprezzato!)
VisualMelon

(Oh, è imbarazzante ... avrei dovuto usarlo %50invece di %'d')
VisualMelon

0

Perl 5 -a , 61 byte

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

Provalo online!

Ha rubato @ user202729's ord%11%6 trucco di

Come?

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

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

Test Suite

spiegazione

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 byte

Questo si avvale di alcuni presupposti che sono perfettamente accettabili per AFAIK. Il numero uno è che tutte le variabili sono inizializzate a zero prima dell'esecuzione; il numero due è che l'ingresso è preso 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 byte

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

Provalo online!

Sopra c'è la mia soluzione che completa gli interi, ma sotto c'è la mia soluzione che gestisce i decimali. L'odioso modo in cui java stampa raddoppia aggiunge altri 55 byes alla partitura. Ho lasciato le nuove righe per rendere il codice più leggibile nella seconda presentazione solo perché è essenzialmente la stessa soluzione con un comando aggiuntivo e una dichiarazione di importazione.

Java (OpenJDK 8) , 219 byte

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

Provalo online!


0

C (gcc) , 120 114 111 byte

-6 byte grazie a ceilingcat.

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

Provalo online!

124 byte

Versione a virgola mobile:

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

Provalo online!

Non mi sono preoccupato di una versione che arrotonda per difetto, ma fa un'eccezione per 0, che sarebbe consentito, se avessi compreso correttamente la catena di commenti.


0

33 , 62 byte

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

Provalo online!

Questo programma prende le istruzioni delimitate da newline

Spiegazione:

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

Il codice prima di quel segmento definisce tutte le funzioni.

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