Đó gần như là Lisp!


14

Thử thách

Thách thức của bạn là thiết kế một trình thông dịch cho một ngôn ngữ giống như ngôn ngữ, từ đó sẽ được đặt ra: GLisp . Mã chương trình cho GLisp sẽ bao gồm một lượng biểu thức lồng nhau tùy ý được biểu thị bằng dấu ngoặc, theo mẫu sau:

(func arg1 arg2 ...)

Lưu ý rằng trình thông dịch phải cho phép các ký tự khoảng trắng bên ngoài trước và sau dấu ngoặc, hàm và đối số.

Các loại

Bạn sẽ thực hiện bốn loại, Integer, List, Boolean và Function. Các số nguyên và giá trị Boolean có thể được chèn rõ ràng vào mã nguồn bằng cú pháp riêng của chúng. Trình thông dịch của bạn phải cho rằng việc chạy các ký tự số biểu thị một Số nguyên (bạn không phải thực hiện cú pháp để chèn rõ ràng các số nguyên âm). Trình thông dịch của bạn cũng phải thừa nhận rằng truefalseđược chỉ định các giá trị Boolean. Các chức năng không thể được xác định rõ ràng bởi người dùng và sẽ luôn trả về một giá trị duy nhất (Danh sách có độ dài bất kỳ được tính là một giá trị).

Chức năng

Các chức năng sau đây được yêu cầu thực hiện và có định dạng Chức năng , Arity . Nếu một Arity nđược tiến hành bằng dấu cộng, thì điều đó biểu thị nhoặc nhiều đối số. Bạn có thể giả định rằng tất cả các đối số được cung cấp cho một hàm là cùng loại, trừ khi được quy định cụ thể khác. Bạn cũng có thể cho rằng nếu không có hành vi nào được chỉ định cho loại certian, thì bạn có thể cho rằng không có đối số nào của hàm đó sẽ thuộc loại đó. Các đối số sẽ được gọi là trong sơ đồ sau:

(func argument1 argument2 ... argumentn)

  • + , 2+

    • Nếu tất cả các đối số thuộc kiểu Integer , bạn phải trả về tổng của các đối số
    • Nếu tất cả các đối số thuộc loại Danh sách , bạn phải trả về cách ghép các đối số theo thứ tự tăng dần ( arg1+arg2+ ...)
    • Nếu tất cả các đối số thuộc loại Boolean , bạn phải trả về logic Tất cả các chuỗi đối số
    • (+ 1 2 3 4 5) -> 15
    • (+ (list 1 2) (list 3 4)) -> (list 1 2 3 4)
    • (+ true true true) -> true
  • - , 2+

    • Nếu tất cả các đối số thuộc kiểu Integer , bạn phải trả về sự khác biệt của các đối số ( arg1-arg2- ...)
    • Nếu tất cả các đối số thuộc loại Boolean , bạn phải trả về logic Bất kỳ chuỗi đối số nào
    • (- 8 4 3) -> 1
    • (- 0 123) -> -123
    • (- true false false true false) -> true
  • * , 2+

    • Nếu tất cả các đối số thuộc kiểu Integer , bạn phải trả về sản phẩm của các đối số
    • Nếu một đối số thuộc loại Danh sách và đối số còn lại thuộc loại Số nguyên (bạn có thể cho rằng đây sẽ chỉ là đối số duy nhất được cung cấp), bạn phải trả về Danh sách mới với các mục trong các arg1lần lặp lại arg2.
    • (* 1 2 3 4 5) -> 120
    • (* (list 1 2 3) 2) -> (list 1 2 3 1 2 3)
  • / , 2+

    • Nếu tất cả các đối số thuộc kiểu Integer , bạn phải trả về thương số của các đối số ( arg/arg2/ ...) (bạn có thể giả sử rằng phép chia được thực hiện tuần tự và phần thập phân ở mỗi bước được cắt ngắn)
    • Nếu một đối số thuộc loại Danh sách và đối số còn lại thuộc loại Hàm , thì bạn phải trả về Danh sách kết quả sau khi arg2đã được ánh xạ qua mọi giá trị
    • (/ 100 10 3) -> 3
    • (/ (list 1 2 3) inc) -> (list 2 3 4)
  • % , 2

    • Nếu tất cả các đối số thuộc kiểu Integer , bạn phải trả về mô-đun của các đối số
    • (% 4 2) -> 0
  • = , 2+

    • Nếu cả loại và giá trị của tất cả các đối số đều giống nhau, bạn phải trả về true. Nếu không, trả lại sai.
    • (= 0 0 0) -> true
    • (= 0 false (list)) -> false
  • danh sách , 0+

    • Bạn phải trả về một danh sách tất cả các đối số, bất kể loại nào. Nếu không có đối số nào được đưa ra, thì bạn phải trả về một danh sách trống
    • (list 3 4 (list 5)) -> (list 3 4 (list 5))
  • bao gồm , 1

    • Nếu đối số thuộc kiểu Integer , bạn phải trả về số nguyên tăng thêm một
    • Nếu đối số thuộc loại Danh sách , bạn phải trả về Danh sách được xoay theo chiều kim đồng hồ một vòng quay duy nhất
    • (inc 1) -> 2
    • (inc (list 1 2 3)) -> (list 3 1 2)
  • ngày 1 tháng 12

    • Nếu đối số thuộc kiểu Integer , bạn phải trả về số nguyên bị giảm bởi một
    • Nếu đối số thuộc loại Danh sách , bạn phải trả về Danh sách được xoay ngược chiều kim đồng hồ một vòng quay
    • (dec 1) -> 0
    • (dec (list 1 2 3)) -> (list 2 3 1)
  • nếu , 3

    • Nếu đưa ra ba đối số thuộc bất kỳ loại nào: Nếu giá trị thật của giá trị arg1là true, return arg2, other returnarg3
    • (if (not (list 1)) 8 false) -> false
  • không , 1

    • Nếu đưa ra một đối số của bất kỳ loại nào, nếu giá trị thật của arg1Sai, trả về true, trả về khác false.
    • (not (list)) -> true
  • len , 1

    • Nếu được cung cấp một đối số của Danh sách loại , trả về độ dài củaarg1
    • (len (list 4 2 true (list 3) (list))) -> 5

Bảng chân lý : 0, (list), false -> false, nơi (list)biểu thị một danh sách trống. Mọi thứ khác là true.

Trình thông dịch của bạn có thể là một chương trình đầy đủ đọc đầu vào nguồn từ stdin hoặc tệp hoặc hàm lấy nguồn dưới dạng chuỗi và trả về giá trị đầu ra.

Nếu chọn cái trước, đầu ra cho Số nguyên chỉ đơn giản là số, đối với Booleanstrue hoặc false, và đối với danh sách là một chuỗi các giá trị được phân tách bằng dấu cách được đặt trong ngoặc (ví dụ: (1 2 3 4 (5 6 7))biểu thị (list 1 2 3 4 (list 5 6 7))).

Nếu chọn cái sau, giá trị phải được trả về trong loại tương ứng của ngôn ngữ thực hiện hoặc, nếu không có loại tương tự tồn tại, một loại tùy chỉnh. Danh sách có thể được trả về dưới dạng Mảng hoặc vectơ nếu ngôn ngữ không có loại Danh sách , Booleans phải được trả về dưới dạng loại Boolean trong ngôn ngữ hoặc loại tùy chỉnh nếu ngôn ngữ không hỗ trợ chúng.

Các trường hợp thử nghiệm

(list 1 2 3 (list 4 5 true))  -> (1 2 3 (4 5 true))
(/ 4000 (+ 1 2 3 4 (* 5 8)))  -> 80
(+ (not (- (len (list 5 6 7)) (/ 10 3))) true)  -> true
(if (           len (list )  ) 4 (if    (+ (= 8 8    8) (not (list 4))) 8 5))  -> 5

Làm rõ

  • Thông dịch viên của bạn có thể xử lý đầu vào không hợp lệ theo bất kỳ cách nào bạn chọn, nhưng nó không được ném ngoại lệ (mặc dù, nó có thể in thông báo lỗi và thoát trơn tru)
  • Các hàm sẽ luôn đánh giá các đối số từ trái sang phải
  • Đầu vào không hợp lệ là bất kỳ đầu vào nào về mặt cú pháp không chính xác. Điều này bao gồm, nhưng không giới hạn ở các dấu ngoặc không khớp, chia cho 0 và các hàm được áp dụng một phần (trừ khi đi lấy tiền thưởng)
  • Đối với =, nếu bất kỳ giá trị nào khác nhau hoặc bất kỳ loại nào khác nhau, hãy trả vềfalse

Tiền thưởng

  • Điểm * 0,8 nếu bạn hỗ trợ các chức năng được áp dụng một phần. Ví dụ, ((+ 2) 3)sẽ giống như (+ 2 3), nhưng cho phép những thứ như (/ (list 1 2 3) (+ 2)). Bạn có thể giả sử rằng một hàm được áp dụng một phần nếu nó nhận được ít hơn số lượng đối số tối thiểu của nó
  • Điểm * 0,85 nếu bạn không đánh giá các đối số được áp dụng iftrừ khi chúng sẽ được trả về

Đây là môn đánh gôn, vì vậy trình thông dịch có số byte thấp nhất sẽ thắng!


Làm thế nào để một người giải thích (if (not (array 1)) 8 false) -> false?
frageum

@feersum bắt tốt, được cho là 8.
Toàn cầu

1
Chúng ta nên đánh giá (+ 3 (if false 5))như thế nào? Nói chung, những gì thực sự là "không trả lại"? Bạn đã không chỉ định bất kỳ loại đơn vị nào sẽ được trả lại
tự hào

3
1. Tại sao (+ bool bool...)logic VÀ và (- bool bool...)logic HOẶC? Ký hiệu vòng tiêu chuẩn sẽ sử dụng +cho OR và *cho AND. 2. "Đầu vào không hợp lệ" có ý định bao gồm các trường hợp như thế (/ 2 0)nào là đúng về mặt cú pháp? 3. Vì =, nếu các giá trị không giống nhau, nó có nên trả về falsekhông? 4. Định nghĩa notxuất hiện là ngược. 5. Mã thông báo là gì? Bạn nói rằng trình thông dịch phải xử lý khoảng trắng thừa, nhưng bạn không nói khoảng trắng mà nó có thể dựa vào. Đối với các câu hỏi phức tạp như thế này, bạn thực sự nên sử dụng hộp cát để có thể kiểm tra thông số kỹ thuật.
Peter Taylor

1
Không rõ ứng dụng một phần nên hoạt động như thế nào: ((+ 2 3) 4)bằng 9hoặc lỗi? Đáng chú ý, đối với các hàm var-arg, không rõ ràng khi nào nên xem xét ứng dụng một phần. Nó thậm chí còn lầy hơn với những thứ như((if true (+ 2 3) (- 5)) 4)
MtnViewMark 7/1/2015

Câu trả lời:


6

Haskell, 1370 1263 1179 1128 1163 1107 1084 byte * 0.8 * 0.85 = 737.12

import Text.Parsec
data V=I Int|L[V]|T|F|P[V]|X|A|S|M|D|U|E|Q|J|K|C|N|W deriving Eq
m Q=0;m C=3;m f|f`elem`[J,K,N,W]=1;m _=2
l=length
x v=[n|I n<-v]
y v=[l|L l<-v]
z v=[0<1|T<-v]++[1<0|F<-v]
(&)f=l.f>>=(.l).(==)
b a|a=T|0<1=F
s(I n)=show n
s(L v)='(':tail(v>>=(' ':).s)++")"
s T=d!!0;s F=d!!1;s _="error"
i(L v)=e$i%v
i v=v
e(P v:a)=e$v++a
e(f:a)|m f>l a=P(f:a)
e(A:a)|x&a=I$sum$x a|y&a=L$concat$y a|z&a=b$and$z a
e(S:a)|x&a=I$f$x a|z&a=b$or$z a
e(M:a)|x&a=I$product$x a
e[M,v,I n]=e$A:replicate n v
e(D:a)|x&a=I$v$x a
e[D,L v,f]=L$map(\a->e[f,a])v
e[U,I a,I b]=I$a`mod`b
e(E:a:v)=b$all(==a)v
e(Q:a)=L a
e[J,I a]=I$a+1
e[J,L[]]=L[]
e[J,L v]=L$last v:init v
e[K,I a]=I$a-1
e[K,L v]=L$drop 1 v++take 1 v
e[C,a,b,c]|a`elem`[I 0,L[],F]=c|0<1=b
e[N,a]=e[C,a,F,T]
e[W,L v]=I$l v
e _=X
f(a:b)=a-sum b
v(a:b)=foldl div a b
(%)f=fmap f
p=k$choice$try%([(I .read)%many1 digit,L%between(w"(")(k$w")")(many$try p)]++zipWith((.return).(>>).w)d[T,F,A,S,M,D,U,E,Q,J,K,C,N,W])
k=(spaces>>)
w=string
d=words"true false + - * / % = list inc dec if not len"
g=either show(s.i).parse p""
main=interact g

Chương trình đầy đủ, đọc stdinvà viết đến stdout. glà phiên bản chức năng, là tốt.

Thực hiện cả hai chức năng một phần, và đánh giá lười biếng if.

Chạy mẫu (của phiên bản chức năng):

λ: g "(list 1 2 3 (list 4 5 true))"
(1 2 3 (4 5 true))

λ: g "(/ 4000 (+ 1 2 3 4 (* 5 8)))"
80

λ: g "(+ (not (- (len (list 5 6 7)) (/ 10 3))) true)"
true

λ: g "(if (           len (list )  ) 4 (if    (+ (= 8 8    8) (not (list 4))) 8 5))"
5

λ: g "(if false (/ 1 0) 5)"
5

λ: g "((+ 2) 3)"
5

λ: g "(/ (list 1 2 3) (+ 2))"
(3 4 5)

Bây giờ có tất cả các bài kiểm tra đơn vị từ mô tả:

λ: runTests 
passed: g "(+ 1 2 3 4 5)" ==> 15
passed: g "(+ (list 1 2) (list 3 4))" ==> (1 2 3 4)
passed: g "(+ true true true)" ==> true
passed: g "(- 8 4 3)" ==> 1
passed: g "(- 0 123)" ==> -123
passed: g "(- true false false true false)" ==> true
passed: g "(* 1 2 3 4 5)" ==> 120
passed: g "(* (list 1 2 3) 2)" ==> (1 2 3 1 2 3)
passed: g "(/ 100 10 3)" ==> 3
passed: g "(/ (list 1 2 3) inc)" ==> (2 3 4)
passed: g "(% 4 2)" ==> 0
passed: g "(= 0 0 0)" ==> true
passed: g "(= 0 false (list))" ==> false
passed: g "(list 3 4 (list 5))" ==> (3 4 (5))
passed: g "(inc 1)" ==> 2
passed: g "(inc (list 1 2 3))" ==> (3 1 2)
passed: g "(dec 1)" ==> 0
passed: g "(dec (list 1 2 3))" ==> (2 3 1)
passed: g "(if (not (list 1)) 8 9)" ==> 9
passed: g "(not (list))" ==> true
passed: g "(len (list 4 2 true (list 3) (list)))" ==> 5
passed: g "(list 1 2 3 (list 4 5 true))" ==> (1 2 3 (4 5 true))
passed: g "(/ 4000 (+ 1 2 3 4 (* 5 8)))" ==> 80
passed: g "(+ (not (- (len (list 5 6 7)) (/ 10 3))) true)" ==> true
passed: g "(if (           len (list )  ) 4 (if    (+ (= 8 8    8) (not (list 4))) 8 5))" ==> 5
passed: g "(if false (/ 1 0) 5)" ==> 5
passed: g "((+ 2) 3)" ==> 5
passed: g "(/ (list 1 2 3) (+ 2))" ==> (3 4 5)

b các trường hợp e[K,L _]bạn có thể sử dụng drop 1 làm phiên bản an toàn tailvà sử dụng takecho phiên bản an toàn headkhi tham gia hai định nghĩa củae[K,L _]
tự hào

bạn có thể sử dụng chức năng. notElemMẹo khác: bạn có thể làm s=stringvà sử dụng nó thay vì cả hai stringchar( s"C"so với char 'C'). một mẹo khác: sử dụng vệ sĩ thay vì ifs
tự hào

Một điều khác tôi nghĩ đến: bạn có thể mã hóa Maybecác giá trị theo danh sách. Nothing[]Just x[x]. Điều này được thoát khỏi các nhà thầu dài và thêm một số chức năng nữa: if p then Just x else Nothing[x|p], (==Nothing)null, danh sách đơn nguyên trở nên giống như có lẽ đơn nguyên, và vân vân.
tự hào

@proudhaskeller Cảm ơn, tất cả được áp dụng!
MtnViewMark 7/1/2015

4

Python 2, 1417 * 0,8 * 0,85 = 963,56

from operator import*
A=type;K="list"
def E():print"E";exit()
def R(G):
 len(G)or E();T=G.pop(0);L=[]
 if"("==T:
  G or E()
  while")"!=G[0]:L+=[R(G)];G or E()
  G.pop(0);return L
 if")"==T:E()
 try:
  x=eval(T.title())
  if Q(x)<2:return x
  E()
 except:return T
H="+ - * / = % if inc dec not len"
Z=lambda y:lambda x:reduce(y,x)
D=dict(zip(H.split(),[[sum,any,0,lambda x:sum((y[1:]for y in x),[K])],[Z(sub)],[Z(mul),all,0,lambda x:x[0][:1]+x[0][1:]*x[1]],[Z(div),lambda x:[K]+map(lambda z:S([x[1],z]if Q(x[1])==2else x[1]+[z]),x[0][1:])],[lambda x:len(set(map(str,x)))<2]*6,[lambda x:x[0]%x[1]],[lambda x:S(x[2])if S(x[0])in[0,[K]]else S(x[1])]*6,[lambda x:x[0]+1,0,0,lambda x:x[0][:1]+x[0][-1:]+x[0][1:-1]],[lambda x:x[0]-1,0,0,lambda x:x[0][:1]+x[0][2:]+[x[0][1]]],[lambda x:x[0]in[0,[K]]]*6,[0]*3+[lambda x:len(x)-1]]))
H=H[:15]+H+" if"
def Q(x):
 t=A(x);w=int,bool,str
 if t in w:return w.index(t)
 if t==list and x:return 5-(2*(x[0]==K)+(str==A(x[0])and len(x)<H.count(x[0])+1))
 E()
def S(G):
 if Q(G)<2:return G
 G or E();c=G[0];r=G[1:];c==K or r or E()
 if c!="if":r=[x if Q(x)in{2,4}else S(x)for x in r]
 if c==K:return[c]+r
 k=map(Q,r);m=min(k);M=max(k);v=[m,[-1,3][{m,M}=={4,5}]][m!=M]
 try:return D[c][v](r)
 except:E()
def C(x):return"(%s)"%" ".join(map(C,x))if A(x)==list else str(x).lower()
def I(G):
 for c in"+-*/%=()":G=G.replace(c," %s "%c)
 return C(S(R(G.strip().split())))
print I(raw_input())

Hoàn thành đại tu. Nếu bạn muốn xem các phiên bản trước, hãy xem lịch sử chỉnh sửa .

Có rất nhiều thứ để chơi gôn. Tôi đang dần dần làm việc với nó.

Với zlib / base64, chúng tôi nhận được 1093 * 0,8 * 0,85 = 743,24 :

import base64,zlib
exec zlib.decompress(base64.b64decode("eJx9VE1P4zAQvedXGEuV7MbttgX2kOADAtSugANbTljWKqSuNku+5Lg0BfHfd8ZJCwjt9tLpdN6bmTczXtuqIFVtbOIqS7KirqwbBufS7WoTX0uaZ42jwcqsyRXjUW2z0tErGps2c4x7/08251FAclOCARwQF9/L+biuajbh8Y1UOiDZmjIq5T0EkjnposDc/s5yQzk9knM10dFNKBXS6fhDzIHJGrexJbnxbNyz+Qhnd0jbSvOc5Ox+7DKXG8YRm63JHWv52SzqwS04Pci0qand3n0fLCQNyYgMyTciyQCBWZmSlUlJWTlsjgYPMk+Kx1VCdlFvtIBfbVLDdqLlwaVcZaljL1nNFuOmzlEhoVSzKURS7sREHFDgYmynppFeQ5s7SEVaCL3WXAv1wJrNY2cUm5yLJM8/YlsQSkVTHXoDKIatmmofvsqe+Xsg0IVFUrPe8RItmcJQ8aI7WcDmUs5M3hiCP0L1ornY02IFBy4cbmMcQ77GWeiWg6h6+P1DDAIHfS0H5xLSzDSHhGhNwCrVBDvVPu2yq+IrUTiFnv/Z9Qjq2/c/+pwQvaP/gmeAVR1Yf4EeyvMlTfTwOPysQssxISzXQi6A81SHi5DiQvpbwGWDXXTyHIx4K+FaxGNV5QJEw7UlDme93a/ddpyVK9Myx7s/pcRzI0m58qvlY05HbDb02kl5zUOUXyI9iomBXVFni3FabUrX+cMpbv9Vf6DL7kD90OcfbmEeHE4xTv0Bxha+QFv4Ka/xL3s4Q0CnR5JCo5GVqt1fVla+zsTJ236YHPe5xR6t7jBA1OdTqQ5BhCeJS3QnLI8LWWQle+LxLfhaNJ6lKgSMVxxr9VqI2zcpX0/E6ZvWqjiSt7o79r7+S2BUz5rZ93Pet3yBc+jCKBs0nA4ooeM/FaTD7Be4wFAdTqnX3HcA2oJnnFdbY3umH5142FcKfdFwNPw2kIzTaA5vnDV1nsD9p4KSQUPoIIVa+vIu2JLBYzYGUngR+P5FgE/gn1Ggtsn2V1bWG3T/BUW+qRU="))

Lưu ý: Nếu bạn thấy điểm của tôi tăng lên, có thể là do tôi đã tìm thấy một vài lỗi


nhiều thách thức về mã hơn so với chơi golf mã nhưng vẫn vậy, 4872 * 0.8 = 3897,6
Def

3

Lisp thường gặp, 868 byte * 0,85 = 737,8

Có phải là gian lận khi thực hiện Lisp với Lisp? Rất nhiều để tối ưu hóa ở đây, vẫn còn.

(SETF (READTABLE-CASE *READTABLE*) :PRESERVE)(PRINC(LABELS((B(X)(FIND X'(true false)))(R(X)(IF X'true'false))(V(X)(MEMBER X'(0()false)))(A(&REST X)(R(NOTANY #'V X)))(O(&REST X)(R(NOTEVERY #'V X)))(E(X &KEY N)(IF(LISTP X)(ECASE(FIRST X)(+(APPLY(IF(EVERY'NUMBERP #1=(MAPCAR(IF N #'IDENTITY #'E)(CDR X)))'+(IF(EVERY'LISTP #1#)'APPEND #'A))#1#))(-(APPLY(IF(EVERY'NUMBERP #1#)'- #'O)#1#))(*(IF(LISTP #2=(CAR #1#))(LOOP FOR I TO(1-(CADR #1#))APPEND #2#)(APPLY'* #1#)))(/(IF(LISTP #2#)(LOOP FOR I IN #2#COLLECT(E `(,(CADR #1#),I):N T))(REDUCE'FLOOR #1#)))(%(APPLY'MOD #1#))(=(R(LOOP FOR I IN(CDR #1#)ALWAYS(EQUAL I #2#))))(list #1#)(inc(IF(LISTP #2#)(APPEND(LAST #2#)(BUTLAST #2#))(1+ #2#)))(dec(IF(LISTP #2#)(APPEND(CDR #2#)`(,(FIRST #2#)))(1- #2#)))(if(IF(V(E(CADR X)))(E(CADDDR X))(E(CADDR X))))(not(R(V #2#)))(len(LENGTH #2#)))X)))(OR(IGNORE-ERRORS(OR(E(READ))"()")):E))

In ra một E trong trường hợp có lỗi trong đầu vào. Chạy mẫu:

$ sbcl --script glisp.lisp
(list 1 2 3 (list 4 5 true))
(1 2 3 (4 5 true))

$ sbcl --script glisp.lisp
(/ 4000 (+ 1 2 3 4 (* 5 8)))
80

$ sbcl --script glisp.lisp
(+ (not (- (len (list 5 6 7)) (/ 10 3))) true)
true

$ sbcl --script glisp.lisp
(if (           len (list )  ) 4 (if    (+ (= 8 8    8) (not (list 4))) 8 5))
5

$ sbcl --script glisp.lisp
(this is an error)
E

$ sbcl --script glisp.lisp
(if (% 4 2) (this is an error) 42)
42

2
miễn là nó không phải là một loại chức năng tệ nạn ...
Def

2

Haskell, 972

r=fst.f
f('(':s)|(f:a,b)<-g s=(f%filter(/="")a,b)
f s=span(`notElem`" ()")s
j=dropWhile(==' ')
g""=([],"")
g s|')':l<-r=([x],l)|(y,t)<-g$j r=(x:y,t)where(x,r)=f$j s
"%"%c=show$foldr(mod.read)(maxBound::Int)c
"+"%c|t(c!!0)<1="(list "++tail(c>>=(' ':).drop 6.init)++")"|t(c!!0)<2=show$sum$map read c|0<1=i$all((=='t').head)c
"-"%c|t(c!!0)<2=show$foldl1(-)$map read c|0<1=i$any((=='t').head)c
"*"%c=fst$f$"(+ "++unwords([1..read$last c]>>init c)++")"
"="%c=i$all(==c!!0)c
"/"%c|t(c!!0)<1,[a,b]<-c="list"%map(\x->b%[x])(fst$g$drop 6 a)|0<1=show$foldl1 div$map read c
"if"%[p,a,b]|elem p["0","()","false"]=b|0<1=a
"list"%c="(list "++unwords c++")"
"len"%[c]=show$length(words c)-1
"inc"%[c]|t c>0=show$read c+1|([],_)<-g$drop 6 c="(list)"|(x,_)<-g$drop 6 c="list"%(last x:init x)
"dec"%[c]|t c<1,(x,_)<-g$drop 6 c="list"%(drop 1 x++take 1 x)|0<1=show$read c-1
"not"%[c]="if"%[c,"false","true"]
s%c="?"
i p|p="true"|0<1="false"
t('(':_)=0
t(c:s)|c<':',c>'/'=1|elem c"th"=2
t _=3

một giải pháp khá khó khăn cái này lưu trữ mọi thứ dưới dạng các chuỗi ở dạng sẵn sàng đầu ra - các loại của chúng có thể được phân biệt bằng chữ cái đầu tiên của chúng - 0..9cho các số, (cho danh sách thoặc fcho booleans và mọi thứ khác cho các hàm.

để chạy sử dụng rchứ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.