Penerjemah golf sederhana

13

Tantangan:

Tugas Anda adalah membuat juru bahasa sederhana untuk bahasa golf yang sederhana.


Memasukkan:

Input akan berupa string yang dipisahkan oleh spasi.

Anda dapat mengganti pemisahan ruang dengan apa yang Anda inginkan


Keluaran:

Keluarkan hasil (angka atau string) yang diperoleh setelah melakukan semua operasi. Jika ada lebih dari satu output, gabung bersama untuk memberikan hasil tunggal (tanpa pemisah). Nilai awal variabel selalu nol. yaitu: Mulai dari0


Sintaks Bahasa:

Bahasa ini memiliki operator berikut:

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)

Contoh:

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 

Larangan:

Ini adalah kode-golf sehingga kode terpendek dalam byte untuk setiap bahasa akan menang.


catatan:

  • Masukan akan selalu valid. (string operator dipisahkan dengan ruang)
  • Anda dapat membulatkan ke bilangan bulat terdekat jika Anda tidak ingin tempat desimal.
Muhammad Salman
sumber
3
Bisakah saya mengambil daftar string? Bisakah saya menggunakan huruf besar lain?
user202729
Tambahkan kasing keluar? keluar seharusnya penting
l4m2
1
@Kaldo: Anda dapat berpisah menggunakan baris baru
Muhammad Salman
3
Hmm, saya tidak akan menyebut bahasa itu "bahasa golf".
Paŭlo Ebermann
1
Ini adalah Deadfish dengan nama perintah ganda dan setengah bukannya persegi dan lebih panjang
Jo King

Jawaban:

8

Bash , 61 byte

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

Cobalah online!

Mengubah program menjadi program dc, lalu mengevaluasinya sebagai kode dc. Ini mengambil input yang dipisahkan oleh baris baru. Perhatikan bahwa dc berbasis stack dan menggunakan notasi polish terbalik.

Input pertama disalurkan ke sed

1i0 pada baris pertama input, masukkan (tambahkan) a 0, ini akan menjadi akumulator

s/.//2g hapus semuanya kecuali karakter pertama pada setiap baris

y"idmhe"+-*/q"transliterate idmheke +-*/qmasing - masing, + - * / adalah perintah aritmatika dan q keluar dari program

/+\|-/pada setiap baris yang mengandung + atau -, i1masukkan 1

/*\|\//pada setiap baris yang mengandung * atau /, i2masukkan 2

/P/pada setiap baris yang berisi P, cdnubah menjadi dn, sama dengan duplikat dan keluaran tanpa baris baru di dc

Sekarang ini dievaluasi sebagai ekspresi dc.

Kritixi Lithos
sumber
2
Saya kira itu tidak masuk akal untuk mengharapkan sedsintaks menjadi lebih asing daripada yang diperkirakan sebelumnya ketika bermain golf.
Mateen Ulhaq
6

Jelly , 21 byte

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

Cobalah online!


Perhatikan bahwa nilai ASCII dari karakter pertama ( idmhPe) modulo 11 adalah modulo 6 yang unik.


Menggunakan modulo 16:

Jelly , 21 byte

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

Cobalah online!

String yang digunakan untuk mengindeks adalah ḤH‘’IȮdalam kasus ini. Tidak ‘’lagi di batas.

pengguna202729
sumber
Menggunakan 11 byte untuk merepresentasikan string 6-byte ... terlalu buruk. Tapi ... “”membutuhkan 2 byte, ¤membutuhkan 1 byte, data itu sendiri membutuhkan 6 byte, masih ada 2 byte yang tersisa untuk melakukan sesuatu. Saat ini dan j, tetapi ịØJatau ṃØJjauh lebih buruk, dan tidak berfungsi (karena Unicode).
user202729
Konsep string jli ("Sebuah string adalah daftar bilangan bulat dengan bendera khusus untuk mempengaruhi pencetakan") sangat bagus.
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)

Cobalah online!

Harus dipanggil dengan source(echo=FALSE)agar nilai pengembalian tidak dicetak secara otomatis. Alternatifnya adalah untuk membungkus semuanyainvisible tapi itu jauh lebih tidak golf (dan merusak jumlah byte saya yang masih bagus).

Giuseppe
sumber
3

05AB1E , 25 byte

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

Cobalah online!

Memetakan setiap fungsi bahasa dengan fungsi 05AB1E yang sesuai (menggunakan karakter pertama dari masing-masing fungsi), dan kemudian mengeksekusi string yang dihasilkan sebagai kode 05AB1E.

Kaldo
sumber
2

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

Cobalah online!

Dapat dibaca:

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]
        ]
    ]
] 
Galen Ivanov
sumber
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

Cobalah online!

-6 dan -3 dengan terima kasih kepada @Rod

-3 dan -2 dengan terima kasih kepada @etene

-1 dengan mengganti "Pri"==xdengan"P"in x

ElPedro
sumber
Anda dapat splitpada "exit"dan mendapatkan blok 1, bukan breaking menyimpan 4 bytes
Rod
1
Anda dapat menghapus tanda kurung di sekitar 'idmh'dan menggunakan findalih-alih index, yang akan menghemat beberapa byte
etene
@Rod - benar-benar dapat mengambil itu sedikit lebih jauh dan berpisah exuntuk menyimpan 2
ElPedro
Anda dapat menggantinya v=(v+1,v-1,v*2,v/2.)dengan v+=(1,-1,v,-v/2.)itu seharusnya bekerja, tidak diuji
Rod
@Rod - memikirkan hal itu tetapi tidak tahu bagaimana cara melakukannya half. Sangat sederhana! Terima kasih.
ElPedro
2

Python 3 , 110 91 82 byte

exit akan menyebabkan program keluar dengan kesalahan.

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

Cobalah online!

mbomb007
sumber
Persingkat nama variabel Anda untuk menghemat 9 byte. i='x+=1';d='x-=1';...dan kemudian dalam execpanggilan Anda , ubah keexec(eval(c[0]))
mypetlion
@mypetlion Terima kasih, tetapi saya menemukan cara yang lebih baik.
mbomb007
Saya pikir ini valid: 82 byte
Lynn
@ Lynn Bagus sekali! Saya tidak bisa memikirkan cara yang bagus untuk melakukan hubungan arus pendek ke printpernyataan itu!
mbomb007
2

JavaScript (ES6), 83 79 byte

Disimpan 4 byte berkat @ l4m2

Iteratif mengganti instruksi dengan output atau string kosong.

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

Cobalah online!

Berkomentar

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()
Arnauld
sumber
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)
14m2
@ l4m2 Ini benar- w<{}benar jahat: 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)juga bekerja
l4m2
2

Arang , 37 35 byte

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

Cobalah online!Tautan adalah untuk mengucapkan versi kode. Terinspirasi oleh jawaban @ RickHitchcock. Penjelasan:

≔⁰η

Kosongkan variabel.

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

Pangkas input di x jika ada, kemudian putar balik dan aktifkan setiap karakter dari (sisa) input.

n≦⊕η

ni n menurunkan variabel.

d≦⊖η

d d menambahkan variabel.

m≦⊗η

m m ultiplies variabel dengan dua (yaitu ganda).

h≦⊘η

h h mengubah variabel.

rIη

rp r int cast variabel string.

Neil
sumber
1
@RickHitchcock Maaf, tidak cukup menguji itu. Saya menemukan solusinya tetapi harganya satu byte.
Neil
2

JavaScript (ES6), 77 75 byte

(Dipinjam ( mencuri ) @ Trik Arnauld menggunakan msebagai nama variabel, menghemat 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)):''

Secara rekursif menyusuri string, mencari huruf berbeda per instruksi dan mengabaikan sisanya:

  • n: inc
  • d: des
  • m: mult
  • h: setengah
  • P: Pri
  • x: keluar

Mengambil keuntungan dari fakta bahwa undefinedini tidak lebih besar dari atau kurang dari 'x', menyebabkan rekursi untuk berhenti di akhir string atau ketika menemukan 'x'di pintu keluar .

Rick Hitchcock
sumber
1
Menindaklanjuti komentar Anda yang dihapus yang tentu saja saya tidak bisa balas lagi, saya lupa menempelkan tautan ke kode yang diperbaiki (d'oh!) Tetapi saya menemukan pendekatan baru yang 2 byte lebih pendek daripada upaya awal saya.
Neil
1

JavaScript (Node.js) , 107 byte

f=s=>s.split` `.map(([o])=>F?0:o=="i"?i++:o=="d"?i--:o=="m"?i*=2:o=="h"?i/=2:o=="P"?S+=i:F=1,F=i=0,S="")&&S

Cobalah online!

DanielIndie
sumber
Ini harus dihitung sebagai 105 byte afaik, selama fungsi Anda tidak menyebut dirinya Anda tidak perlu menghitungf=
Brian H.
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`))
Brian H.
sumber
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
Jujhar Singh
sumber
1

Python 3 , 114 110 109 116 byte

Sebenarnya akan mengambil dua byte lebih sedikit di Python 2 karena execmerupakan pernyataan dan tidak perlu tanda kurung ...

  • Disimpan 4 byte tambahan berkat @ElPedro

  • Menyimpan byte ekstra dengan mengambil keuntungan dari fakta yang findmengembalikan -1 pada kesalahan, yang kemudian dapat digunakan sebagai indeks

  • +7 byte karena saya tidak memperhatikan aturan 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()))

Cobalah online!

Memetakan karakter pertama dari setiap kata input ke sepotong kode Python. Ini kemudian digabungkan dan execdiedit.

Pendekatan yang cukup mudah, yang mungkin bisa bermain golf sedikit lebih. Kesulitan sebagian besar berada dalam menemukan bentuk terpendek dari banyak yang mungkin ...

etene
sumber
112 Cobalah secara online! jika Anda memiliki perintah sebagai spasi string terpisah dan membaginya.
ElPedro
1
110 sebenarnya saat kurung bisa Coba online!
ElPedro
Ini tidak memberikan output yang benar. Pertanyaannya mengatakan Anda harus mencetak tanpa pemisah, jadi Anda perlu print(i,end=''). Lihat test case ke-4.
mbomb007
Saya tidak memperhatikan, saya akan memperbaikinya. Terima kasih!
etene
@etene Comment ketika Anda sudah memperbaikinya dan saya akan menghapus downvote saya.
mbomb007
1

Ruby + -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]}

Cobalah online!

Cukup mudah. Untuk huruf pertama dari setiap kata, temukan string perintah yang sesuai dan evalitu. Menggunakan divisi integer, dan exitsdengan melempar a ZeroDivisionError.

-5 byte: Gunakan .ord%11%6alih-alih pencarian string. Kredit menjadi pengguna202729

-3 byte: .ordhanya mempertimbangkan karakter pertama dari string, jadi saya bisa melewatkan a [0].

-8 byte: Gunakan -aflag untuk membagi input secara otomatis, terima kasih kepada Kirill L.

benj2240
sumber
1
Anda dapat menyimpan lebih banyak byte dengan menambahkan -aopsi untuk melakukan autosplit untuk Anda, seperti ini
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🍉🍓🍇🍎🍉🍉🍉

Cobalah 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🔤
🍉
X1M4L
sumber
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

Cobalah online!

Kotor.

	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
Giuseppe
sumber
0

C # (.NET Core), 186 Bytes

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;}}}
Romen
sumber
Anda dapat mencukur 26bytes dari ini dengan melakukan beberapa hal sederhana, seperti mendeklarasikan idengan v, berkonsultasi dengan tabel ASCII sehingga Anda dapat menggunakan angka kecil, menata ulang ifs, dan kemudian menggunakan ternary: 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 penjelasan tentang cara kerjanya dan cara menggunakan itu (mis. mengharapkan args baris perintah) selalu dihargai!)
VisualMelon
(Oh itu memalukan ... Seharusnya saya menggunakan %50alih-alih %'d')
VisualMelon
0

Perl 5 -a , 61 byte

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

Cobalah online!

ord%11%6Trik mencuri @ user202729

Bagaimana?

-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
Xcali
sumber
0

Pyth, 44 Bytes

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

Test Suite

penjelasan

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)
KarlKastor
sumber
0

TI-BASIC, 112 byte

Ini mengambil keuntungan dari beberapa asumsi yang AFAIK dapat diterima sepenuhnya. Nomor satu adalah bahwa semua variabel diinisialisasi ke nol sebelum eksekusi; nomor dua adalah input yang diambil 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
kamoroso94
sumber
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;}}

Cobalah online!

Di atas adalah solusi saya yang membulatkan ke bilangan bulat, tetapi di bawah ini adalah solusi saya yang menangani desimal. Cara menjengkelkan yang mencetak java ganda menambahkan 55 bye ke skor. Saya meninggalkan baris baru untuk membuat kode lebih mudah dibaca dalam pengiriman kedua hanya karena itu pada dasarnya solusi yang sama dengan satu perintah tambahan dan pernyataan impor.

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

Cobalah online!

X1M4L
sumber
0

C (gcc) , 120 114 111 byte

-6 bytes berkat 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);}

Cobalah online!

124 byte

Versi titik-mengambang:

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

Cobalah online!

Saya tidak peduli dengan versi yang dibulatkan ke bawah, tetapi membuat pengecualian untuk 0, yang akan diizinkan, jika saya memahami rantai komentar dengan benar.

gastropner
sumber
0

33 , 62 byte

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

Cobalah online!

Program ini menerima instruksi yang dibatasi oleh baris baru

Penjelasan:

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

Kode sebelum segmen itu mendefinisikan semua fungsi.

TheOnlyMrCat
sumber