Thông dịch viên chơi golf đơn giản


13

Thử thách:

Công việc của bạn là tạo ra một trình thông dịch đơn giản cho một ngôn ngữ chơi golf đơn giản.


Đầu vào:

Đầu vào sẽ ở dạng chuỗi được phân tách bằng dấu cách.

Bạn có thể thay thế phân tách không gian bằng những gì bạn muốn


Đầu ra:

Xuất kết quả (một số hoặc một chuỗi) thu được sau khi thực hiện tất cả các hoạt động. Nếu có nhiều đầu ra kết hợp với nhau để đưa ra một kết quả (không có dấu phân cách). Giá trị ban đầu của biến luôn bằng không. tức là: Nó bắt đầu từ0


Cú pháp ngôn ngữ:

Ngôn ngữ có các toán tử sau:

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)

Ví dụ:

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 

Sự hạn chế:

Đây là môn đánh gôn để mã ngắn nhất tính theo byte cho mỗi ngôn ngữ sẽ giành chiến thắng.


Ghi chú:

  • Đầu vào sẽ luôn có hiệu lực. (chuỗi toán tử được phân tách bằng dấu cách)
  • Bạn có thể làm tròn xuống số nguyên gần nhất nếu bạn không muốn vị trí thập phân.

3
Tôi có thể lấy một danh sách các chuỗi? Tôi có thể sử dụng viết hoa khác không?
dùng202729

Thêm trường hợp thoát? lối ra nên có vấn đề
l4m2

1
@Kaldo: Bạn có thể tách bằng các dòng mới
Muhammad Salman

3
Hmm, tôi sẽ không gọi ngôn ngữ đó là "ngôn ngữ chơi gôn".
Paŭlo Ebermann

1
Đây là Deadfish với gấp đôi và một nửa thay vì tên lệnh vuông và dài hơn
Jo King

Câu trả lời:


8

Bash , 61 byte

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

Hãy thử trực tuyến!

Chuyển đổi chương trình thành chương trình dc, sau đó đánh giá nó là mã dc. Điều này có đầu vào được phân tách bằng dòng mới. Lưu ý rằng dc dựa trên ngăn xếp và sử dụng ký hiệu đánh bóng ngược.

Đầu vào đầu tiên được dẫn đến sed

1i0 trên dòng đầu tiên, chèn (trả trước) 0, đây sẽ là bộ tích lũy

s/.//2g xóa mọi thứ trừ ký tự đầu tiên trên mỗi dòng

y"idmhe"+-*/q"chuyển idmhethành +-*/qtương ứng, + - * / là các lệnh số học và q thoát khỏi chương trình

/+\|-/trên mỗi dòng chứa + hoặc -, i1chèn 1

/*\|\//trên mỗi dòng chứa * hoặc /, i2chèn 2

/P/trên mỗi dòng chứa P, cdnthay đổi nó thành dn, tương đương với trùng lặp và đầu ra mà không có dòng mới trong dc

Bây giờ điều này được đánh giá là một biểu thức dc.


2
Tôi cho rằng không phải là không có lý khi hy vọng sedcú pháp sẽ trở nên xa lạ hơn so với những gì đã nghĩ trước đây khi chơi golf.
Mateen Ulhaq

6

Thạch , 21 byte

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

Hãy thử trực tuyến!


Lưu ý rằng các giá trị ASCII của các ký tự đầu tiên ( idmhPe) modulo 11 là modulo 6 duy nhất.


Sử dụng modulo 16:

Thạch , 21 byte

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

Hãy thử trực tuyến!

Chuỗi được sử dụng để lập chỉ mục là ḤH‘’IȮtrong trường hợp này. Các ‘’không còn trên ranh giới.


Sử dụng 11 byte để thể hiện chuỗi 6 byte là ... quá tệ. Nhưng ... “”mất 2 byte, ¤mất 1 byte, dữ liệu tự mất 6 byte, còn lại 2 byte để làm gì đó. Hiện tại, nó j, ịØJhoặc ṃØJtệ hơn nhiều, và không hoạt động (vì Unicode).
dùng202729

Khái niệm chuỗi của jli ("Chuỗi là danh sách các số nguyên có cờ đặc biệt ảnh hưởng đến in") thật tuyệt vời.
dùng202729

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)

Hãy thử trực tuyến!

Phải được gọi với source(echo=FALSE)để ngăn giá trị trả về được in tự động. Giải pháp thay thế sẽ là bọc mọi thứ vàoinvisible nhưng nó ít chơi gôn hơn (và làm hỏng số byte đẹp [vẫn] của tôi).


3

05AB1E , 25 byte

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

Hãy thử trực tuyến!

Ánh xạ từng hàm ngôn ngữ với hàm 05AB1E tương ứng (sử dụng char đầu tiên của mỗi hàm), sau đó thực thi chuỗi kết quả là mã 05AB1E.


2

Màu đỏ , 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]]]

Hãy thử trực tuyến!

Có thể đọc được

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

Hãy thử trực tuyến!

-6 và -3 cảm ơn @Rod

-3 và -2 nhờ vào @etene

-1 bằng cách thay thế "Pri"==xbằng"P"in x


bạn có thể splitvào "exit"và nhận được khối 1, thay vì breaking tiết kiệm 4 byte
Rod

1
Bạn có thể xóa các dấu ngoặc đơn xung quanh 'idmh'và sử dụng findthay vì index, điều đó sẽ tiết kiệm một vài byte
etene

@Rod - thực sự có thể tiến xa hơn một chút và tách ra exđể cứu thêm 2
ElPedro

Bạn có thể thay thế v=(v+1,v-1,v*2,v/2.)bằng v+=(1,-1,v,-v/2.)nó nên hoạt động, mặc dù chưa được thử nghiệm
Rod

@Rod - nghĩ về điều đó nhưng không thể tìm ra cách để làm half. Quá đơn giản! Cảm ơn.
ElPedro

2

Python 3 , 110 91 82 byte

exit sẽ khiến chương trình thoát ra với một lỗi.

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

Hãy thử trực tuyến!


Rút ngắn tên biến của bạn để lưu 9 byte. i='x+=1';d='x-=1';...và sau đó trong execcuộc gọi của bạn , hãy đổi nó thànhexec(eval(c[0]))
mypetlion

@mypetlion Cảm ơn, nhưng tôi tìm thấy một cách tốt hơn.
mbomb007

Tôi nghĩ rằng điều này là hợp lệ: 82 byte
Lynn

@Lynn Thật tuyệt! Tôi không thể nghĩ ra một cách hay để ngắn mạch cho printtuyên bố!
mbomb007

2

JavaScript (ES6), 83 79 byte

Đã lưu 4 byte nhờ @ l4m2

Lặp lại thay thế các hướng dẫn bằng chuỗi đầu ra hoặc chuỗi rỗng.

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

Hãy thử trực tuyến!

Đã bình luận

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 Đây w<{}là tà ác thuần túy: 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)cũng làm việc
l4m2

2

Than , 37 35 byte

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

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã. Lấy cảm hứng từ câu trả lời của @ RickHitchcock. Giải trình:

≔⁰η

Xóa biến.

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

Cắt ngắn đầu vào tại x nếu có một, sau đó lặp lại và bật từng ký tự của (phần còn lại) của đầu vào.

n≦⊕η

ni n cắt biến.

d≦⊖η

d d làm thay đổi biến.

m≦⊗η

m m ultiplies biến bằng hai (tức là nhân đôi).

h≦⊘η

h h alves biến.

rIη

rp r ints biến biến thành chuỗi.


1
@RickHitchcock Xin lỗi, đã không kiểm tra đủ kỹ lưỡng. Tôi tìm thấy một cách giải quyết nhưng nó làm tôi tốn một byte.
Neil

2

JavaScript (ES6), 77 75 byte

(Mượn ( lấy trộm ) @ Arnauld lừa sử dụng mlàm tên biến, tiết kiệm 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)):''

Đệ quy đi bộ chuỗi, tìm kiếm các chữ cái riêng biệt cho mỗi hướng dẫn và bỏ qua phần còn lại:

  • n: inc
  • d: tháng mười hai
  • m: nhiều
  • h: một nửa
  • P: Giải
  • x: thoát

Lợi dụng thực tế là undefinedkhông phải là lớn hơn cũng không ít hơn 'x', làm cho đệ quy để dừng ở phần cuối của chuỗi hoặc khi gặp phải 'x'lối ra .


1
Theo dõi nhận xét đã xóa của bạn mà dĩ nhiên tôi không thể trả lời được nữa, tôi đã quên dán vào liên kết đến mã đã sửa (d'oh!) Nhưng dù sao tôi cũng tìm thấy một cách tiếp cận mới ngắn hơn 2 byte so với nỗ lực ban đầu của tôi.
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

Trên thực tế, sẽ mất ít hơn hai byte trong Python 2 vì đây execlà một câu lệnh và không cần dấu ngoặc đơn ...

  • Đã lưu thêm 4 byte nhờ @ElPedro

  • Đã lưu thêm một byte bằng cách lợi dụng thực tế findtrả về -1 lỗi, sau đó có thể được sử dụng làm chỉ mục

  • +7 byte bởi vì tôi đã không nhận thấy quy tắc không có dòng mới :(

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

Hãy thử trực tuyến!

Ánh xạ ký tự đầu tiên của mỗi từ đầu vào thành một đoạn mã Python. Chúng sau đó được nối vàexec ed.

Cách tiếp cận khá đơn giản, có lẽ có thể được đánh gôn nhiều hơn một chút. Khó khăn chủ yếu nằm ở việc tìm ra hình thức ngắn nhất trong số nhiều hình thức có thể ...


112 Hãy thử trực tuyến! nếu bạn có các lệnh như một chuỗi tách biệt không gian và phân tách nó.
ElPedro

1
110 trong thực tế là dấu ngoặc có thể đi thử trực tuyến!
ElPedro

Điều này không cung cấp đầu ra chính xác. Câu hỏi nói rằng bạn phải in mà không có dấu phân cách, vì vậy bạn cần print(i,end=''). Xem trường hợp thử nghiệm thứ 4.
mbomb007

Tôi đã không nhận thấy, tôi sẽ sửa nó. Cảm ơn !
etene

@etene Nhận xét khi bạn đã sửa nó và tôi sẽ xóa downvote của tôi.
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]}

Hãy thử trực tuyến!

Khá đơn giản. Đối với chữ cái đầu tiên của mỗi từ, tìm chuỗi lệnh tương ứng và evalnó. Sử dụng phép chia số nguyên, và exitsbằng cách ném a ZeroDivisionError.

-5 byte: Sử dụng .ord%11%6thay vì tra cứu chuỗi. Tín dụng đi đến dùng202729

-3 byte: .ordchỉ xem xét ký tự đầu tiên của chuỗi, vì vậy tôi có thể bỏ qua a [0].

-8 byte: Sử dụng -acờ để tự động phân tách đầu vào, nhờ vào Kirill L.


1
Bạn có thể tiết kiệm nhiều byte hơn bằng cách thêm -atùy chọn để thực hiện tự động cho bạn, như thế này
Kirill L.

1

Biểu tượng cảm xúc , 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🍉🍓🍇🍎🍉🍉🍉

Hãy thử trực tuyến!

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

Hãy thử trực tuyến!

Tổng.

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

Bạn có thể cạo 26bytes tắt này bằng cách thực hiện một vài điều đơn giản, giống như tuyên bố ivới v, tư vấn một bảng mã ASCII, do đó bạn có thể sử dụng với số lượng nhỏ, sắp xếp lại if, và sau đó sử dụng một 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 giải thích về cách thức hoạt động và cách sử dụng nó (ví dụ: mong đợi dòng lệnh args) luôn được đánh giá cao!)
VisualMelon

(Ôi thật đáng xấu hổ ... Tôi nên sử dụng %50thay vì %'d')
VisualMelon

0

Perl 5 -a , 61 byte

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

Hãy thử trực tuyến!

Lấy trộm @ user202729 ord%11%6 lừa

Làm sao?

-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

Bình, 44 byte

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

Phòng thử nghiệm

giải trình

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

Điều này tận dụng một số giả định mà AFAIK hoàn toàn chấp nhận được. Số một là tất cả các biến được khởi tạo về 0 trước khi thực hiện; số hai là đầu vào được thực hiện thông qua 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;}}

Hãy thử trực tuyến!

Trên đây là giải pháp của tôi làm tròn số nguyên, nhưng dưới đây là giải pháp của tôi xử lý số thập phân. Cách đáng ghét mà java in tăng gấp đôi thêm 55 điểm nữa vào điểm số. Tôi đã để lại các dòng mới để làm cho mã dễ đọc hơn trong lần gửi thứ hai vì về cơ bản đó là cùng một giải pháp với một lệnh bổ sung và một câu lệnh nhập.

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

Hãy thử trực tuyến!


0

C (gcc) , 120 114 111 byte

-6 byte nhờ vào trần nhà.

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

Hãy thử trực tuyến!

124 byte

Phiên bản dấu phẩy động:

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

Hãy thử trực tuyến!

Tôi không bận tâm với một phiên bản làm tròn xuống, nhưng tạo một ngoại lệ cho 0, sẽ được cho phép, nếu tôi hiểu chính xác chuỗi nhận xét.


0

33 , 62 byte

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

Hãy thử trực tuyến!

Chương trình này có các hướng dẫn được phân định bởi các dòng mới

Giải trình:

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

Mã trước đoạn đó xác định tất cả các chức năng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.