เกือบจะกระเพื่อม!


14

ท้าทาย

ความท้าทายของคุณคือการออกแบบสำหรับล่ามภาษากระเพื่อมเหมือนซึ่งจะไปจากที่นี่มาได้รับการประกาศเกียรติคุณ: GLisp รหัสโปรแกรมสำหรับGLispจะประกอบด้วยจำนวนของนิพจน์ที่ซ้อนกันที่แสดงโดยวงเล็บในรูปแบบต่อไปนี้โดยพลการ:

(func arg1 arg2 ...)

โปรดทราบว่าล่ามจะต้องอนุญาตสำหรับอักขระช่องว่างภายนอกก่อนและหลังวงเล็บฟังก์ชั่นและข้อโต้แย้ง

ประเภท

คุณจะใช้งานสี่ประเภท, จำนวนเต็ม, รายการ, บูลีนและฟังก์ชั่น ค่าจำนวนเต็มและบูลีนสามารถแทรกอย่างชัดเจนในซอร์สโค้ดด้วยไวยากรณ์ของตัวเอง ล่ามของคุณต้องสมมติว่าการใช้อักขระตัวเลขหมายถึงจำนวนเต็ม (คุณไม่จำเป็นต้องใช้ไวยากรณ์เพื่อแทรกจำนวนเต็มลบอย่างชัดเจน) ล่ามของคุณจะต้องถือว่าtrueและfalseได้รับการกำหนดค่าบูลีน ฟังก์ชั่นไม่สามารถกำหนดได้อย่างชัดเจนโดยผู้ใช้และจะส่งกลับค่าเดียวเสมอ (รายการที่มีความยาวนับเป็นค่าเดียว)

ฟังก์ชั่น

ฟังก์ชั่นต่อไปนี้จะต้องได้รับการดำเนินการและอยู่ในรูปแบบฟังก์ชั่น , arity หาก Arity nดำเนินการต่อโดยเครื่องหมายบวกแสดงว่าnมีการโต้แย้งหรือมากกว่า คุณอาจสมมติว่าอาร์กิวเมนต์ทั้งหมดที่กำหนดให้กับฟังก์ชันนั้นเป็นประเภทเดียวกันเว้นแต่จะระบุไว้เป็นอย่างอื่น คุณอาจคิดว่าหากไม่มีการระบุพฤติกรรมสำหรับประเภทใบรับรองคุณอาจสมมติว่าไม่มีข้อโต้แย้งของฟังก์ชันนั้น ๆ ที่จะเป็นประเภทนั้น อาร์กิวเมนต์จะถูกอ้างถึงในแผนภาพต่อไปนี้:

(func argument1 argument2 ... argumentn)

  • + , 2+

    • หากอาร์กิวเมนต์ทั้งหมดเป็นประเภทจำนวนเต็มคุณต้องส่งคืนผลรวมของข้อโต้แย้ง
    • ถ้าขัดแย้งทั้งหมดเป็นประเภทรายการคุณต้องกลับมาเรียงต่อกันของการขัดแย้งในการเรียงลำดับ ( arg1+arg2+ ...)
    • หากอาร์กิวเมนต์ทั้งหมดเป็นประเภทBooleanคุณต้องส่งคืนตรรกะทั้งหมดของลำดับอาร์กิวเมนต์
    • (+ 1 2 3 4 5) -> 15
    • (+ (list 1 2) (list 3 4)) -> (list 1 2 3 4)
    • (+ true true true) -> true
  • - , 2+

    • หากข้อโต้แย้งทั้งหมดเป็นประเภทจำนวนเต็มคุณต้องส่งกลับข้อแตกต่างของข้อโต้แย้ง ( arg1-arg2- ...)
    • หากอาร์กิวเมนต์ทั้งหมดเป็นประเภทBooleanคุณต้องส่งคืนตรรกะใด ๆ ตามลำดับของอาร์กิวเมนต์
    • (- 8 4 3) -> 1
    • (- 0 123) -> -123
    • (- true false false true false) -> true
  • * , 2+

    • หากข้อโต้แย้งทั้งหมดเป็นประเภทจำนวนเต็มคุณต้องส่งคืนผลิตภัณฑ์ของข้อโต้แย้ง
    • หากอาร์กิวเมนต์หนึ่งเป็นประเภทรายการและอีกประเภทหนึ่งเป็นจำนวนเต็ม (คุณอาจคิดว่าสิ่งเหล่านี้จะเป็นเพียงอาร์กิวเมนต์ที่กำหนดเท่านั้น) คุณจะต้องส่งคืนรายการใหม่พร้อมกับรายการในเวลาที่arg1ซ้ำarg2กัน
    • (* 1 2 3 4 5) -> 120
    • (* (list 1 2 3) 2) -> (list 1 2 3 1 2 3)
  • / , 2+

    • หากข้อโต้แย้งทั้งหมดเป็นประเภทจำนวนเต็มคุณต้องส่งคืนผลหารของข้อโต้แย้ง ( arg/arg2/ ...) (คุณอาจถือว่าการหารนั้นทำตามลำดับและส่วนทศนิยมในทุกขั้นตอนจะถูกตัดทอน)
    • หากอาร์กิวเมนต์หนึ่งเป็นประเภทรายการและอีกประเภทหนึ่งเป็นประเภทฟังก์ชั่นคุณจะต้องส่งคืนรายการผลลัพธ์หลังจากที่arg2ได้รับการแมปผ่านทุกค่า
    • (/ 100 10 3) -> 3
    • (/ (list 1 2 3) inc) -> (list 2 3 4)
  • % , 2

    • หากอาร์กิวเมนต์ทั้งหมดเป็นประเภทจำนวนเต็มคุณต้องส่งคืนโมดูลัสของอาร์กิวเมนต์
    • (% 4 2) -> 0
  • = , 2+

    • หากทั้งชนิดและค่าของอาร์กิวเมนต์ทั้งหมดเหมือนกันคุณต้องส่งคืนค่าจริง มิฉะนั้นส่งคืน false
    • (= 0 0 0) -> true
    • (= 0 false (list)) -> false
  • รายการ 0+

    • คุณต้องส่งคืนรายการอาร์กิวเมนต์ทั้งหมดโดยไม่คำนึงถึงชนิด หากไม่มีการกำหนดอาร์กิวเมนต์คุณต้องส่งคืนรายการว่าง
    • (list 3 4 (list 5)) -> (list 3 4 (list 5))
  • inc 1

    • ถ้าอาร์กิวเมนต์เป็นประเภทจำนวนเต็มคุณต้องส่งคืนค่าจำนวนเต็มเพิ่มขึ้นทีละหนึ่ง
    • ถ้าอาร์กิวเมนต์เป็นประเภทรายการคุณต้องส่งคืนรายการที่หมุนตามเข็มนาฬิกาเป็นการหมุนครั้งเดียว
    • (inc 1) -> 2
    • (inc (list 1 2 3)) -> (list 3 1 2)
  • ธ.ค. 1

    • หากอาร์กิวเมนต์เป็นประเภทจำนวนเต็มคุณต้องส่งคืนค่าจำนวนเต็มลดลงหนึ่งค่า
    • ถ้าอาร์กิวเมนต์เป็นชนิดรายการคุณต้องส่งคืนรายการที่หมุนทวนเข็มนาฬิกาเป็นการหมุนครั้งเดียว
    • (dec 1) -> 0
    • (dec (list 1 2 3)) -> (list 2 3 1)
  • ถ้า 3

    • หากมีข้อโต้แย้งสามประเภท: ถ้าค่าความจริงarg1เป็นจริงให้ส่งarg2คืนarg3
    • (if (not (list 1)) 8 false) -> false
  • ไม่ใช่ 1

    • หากได้รับข้อโต้แย้งของชนิดใด ๆ ถ้าค่าความจริงของarg1คือ False ผลตอบแทนอื่นกลับมาtruefalse
    • (not (list)) -> true
  • เลน 1

    • หากได้รับการโต้แย้งจากประเภทรายการกลับความยาวของarg1
    • (len (list 4 2 true (list 3) (list))) -> 5

ตารางความจริง: 0, (list), false -> falseโดยที่(list)หมายถึงรายการที่ว่างเปล่า trueทุกสิ่งทุกอย่างเป็น

ล่ามของคุณอาจเป็นโปรแกรมเต็มรูปแบบที่อ่านอินพุตต้นฉบับจาก stdin หรือไฟล์หรือฟังก์ชั่นที่รับซอร์สเป็นสตริงและส่งคืนค่าเอาต์พุต

หากเลือกแบบก่อนหน้าเอาต์พุตสำหรับจำนวนเต็มเป็นเพียงตัวเลขสำหรับBooleansคือtrueหรือfalseและสำหรับรายการเป็นลำดับที่คั่นด้วยช่องว่างของค่าที่อยู่ในวงเล็บ (เช่น(1 2 3 4 (5 6 7))หมายถึง(list 1 2 3 4 (list 5 6 7)))

หากเลือกหลังจะต้องส่งคืนค่าในประเภทที่สอดคล้องกันของภาษาที่ใช้งานหรือหากไม่มีประเภทที่คล้ายกันประเภทที่กำหนดเองอยู่ รายการสามารถกลับมาเป็นอาร์เรย์หรือพาหะถ้าภาษาที่ไม่ได้มีรายการประเภทBooleansควรจะกลับเป็นชนิดบูลีนในภาษาหรือประเภทที่กำหนดเองถ้าภาษาไม่สนับสนุนพวกเขา

กรณีทดสอบ

(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

ชี้แจง

  • ล่ามของคุณอาจจัดการกับการป้อนข้อมูลที่ไม่ถูกต้องในวิธีที่คุณเลือก แต่มันจะต้องไม่เกิดข้อยกเว้น (แม้ว่ามันอาจพิมพ์ข้อความผิดพลาดและออกอย่างราบรื่น)
  • ฟังก์ชั่นจะประเมินข้อโต้แย้งจากซ้ายไปขวาเสมอ
  • อินพุตไม่ถูกต้องคืออินพุตใด ๆ ที่ไม่ถูกต้องทางไวยากรณ์ ซึ่งรวมถึง แต่ไม่ จำกัด เพียงวงเล็บเหลี่ยมที่ไม่ตรงกันการหารด้วยศูนย์และฟังก์ชั่นที่นำไปใช้บางส่วน (ยกเว้นจะได้โบนัส)
  • สำหรับ=หากค่าใด ๆ นั้นแตกต่างกันหรือประเภทใด ๆ แตกต่างกันให้ส่งคืนfalse

โบนัส

  • คะแนน * 0.8หากคุณรองรับฟังก์ชั่นที่ใช้บางส่วน ยกตัวอย่างเช่น((+ 2) 3)จะเป็นเช่นเดียวกับแต่ช่วยให้สิ่งต่างๆเช่น(+ 2 3) (/ (list 1 2 3) (+ 2))คุณอาจคิดว่าฟังก์ชั่นบางส่วนถูกนำไปใช้ถ้ามันได้รับน้อยกว่าจำนวนขั้นต่ำของการขัดแย้ง
  • คะแนน * 0.85หากคุณไม่ได้ประเมินอาร์กิวเมนต์ที่ใช้กับifถ้าพวกเขาจะถูกส่งกลับ

นี่คือโค้ดกอล์ฟดังนั้นล่ามที่มีจำนวนไบต์ต่ำสุดชนะ!


คนเราตีความได้(if (not (array 1)) 8 false) -> falseอย่างไร
feersum

@feersum การจับที่ดีน่าจะเป็น 8
globby

1
เราควรประเมิน(+ 3 (if false 5))อย่างไร โดยทั่วไปแล้วสิ่งที่ "คืนค่าอะไร" คืออะไร? คุณไม่ได้ระบุประเภทหน่วยใด ๆ ที่จะรับการเรียกคืน
ภูมิใจ Haskeller

3
1. ทำไม(+ bool bool...)ตรรกะและและ(- bool bool...)ตรรกะหรือ? สัญกรณ์แหวนมาตรฐานจะใช้+สำหรับ OR และ*สำหรับและ 2. "การป้อนข้อมูลที่ไม่ถูกต้อง" มีวัตถุประสงค์เพื่อครอบคลุมกรณีเช่นนี้(/ 2 0)ซึ่งถูกต้องตามหลักไวยากรณ์หรือไม่ 3. สำหรับ=หากค่าไม่เหมือนกันทั้งหมดจะต้องส่งคืนfalseหรือไม่ 4. คำจำกัดความของnotดูเหมือนจะย้อนกลับ 5. โทเค็นคืออะไร คุณพูดว่าล่ามจะต้องจัดการช่องว่างพิเศษ แต่คุณไม่ต้องพูดว่าช่องว่างนั้นสามารถพึ่งพาได้ สำหรับคำถามที่ซับซ้อนเช่นนี้คุณควรใช้แซนด์บ็อกซ์เพื่อตรวจสอบข้อมูลจำเพาะ
ปีเตอร์เทย์เลอร์

1
ไม่ชัดเจนว่าแอปพลิเคชันบางส่วนทำงานอย่างไร: ((+ 2 3) 4)เท่ากับ9หรือมีข้อผิดพลาด โดยเฉพาะอย่างยิ่งสำหรับฟังก์ชั่น var-arg มันไม่ชัดเจนเมื่อหนึ่งควรพิจารณาใบสมัครบางส่วน มันจะยิ่งยุ่งเหยิงไปกับสิ่งต่าง ๆ เช่น((if true (+ 2 3) (- 5)) 4)
MtnViewMark

คำตอบ:


6

Haskell, 1370 1263 1179 1128 1163 1107 1084 ไบต์ * 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

โปรแกรมเต็มรูปแบบ, การอ่านและการเขียนเพื่อstdin เป็นรุ่นฟังก์ชั่นเช่นกันstdoutg

ifการดำเนินการทั้งสองฟังก์ชั่นบางส่วนและการประเมินผลขี้เกียจของ

ตัวอย่างการรัน (ของเวอร์ชั่นฟังก์ชั่น):

λ: 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)

ขณะนี้มีการทดสอบหน่วยทั้งหมดจากคำอธิบาย:

λ: 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 กรณีที่ e[K,L _]คุณสามารถใช้drop 1 เป็นเวอร์ชันที่ปลอดภัยtailและใช้takeสำหรับเวอร์ชันที่ปลอดภัยในการheadเข้าร่วมสองคำจำกัดความe[K,L _]
ภูมิใจ haskeller

คุณสามารถใช้ฟังก์ชั่นnotElemเคล็ดลับอื่น ๆ : คุณสามารถทำได้s=stringและใช้งานแทนทั้งสองstringและchar( s"C"เทียบกับchar 'C') เคล็ดลับอื่น: ใช้ guards แทนifs
ภูมิใจ haskeller

อีกสิ่งที่ฉันคิด: คุณสามารถเข้ารหัสMaybeค่าตามรายการ Nothingเป็น[]และเป็นJust x [x]นี้ได้รับการกำจัดของการก่อสร้างนานและเพิ่มฟังก์ชันการทำงานบางอย่างเพิ่มเติม: if p then Just x else Nothingเป็น[x|p], (==Nothing)คือnull, monad รายการจะกลายเป็นเหมือนกับบางที Monad และอื่น ๆ
ภูมิใจ haskeller

@proudhaskeller ขอบคุณทุกคนสมัครแล้ว!
MtnViewMark

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

ยกเครื่องให้สมบูรณ์ หากคุณต้องการที่จะเห็นรุ่นก่อนหน้าให้ตรวจสอบประวัติการแก้ไข

มีอะไรอีกมากมายที่จะต้องตีกอล์ฟ ฉันกำลังทำงานอย่างช้าๆ

ด้วย zlib / base64 เราได้รับ1,093 * 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="))

หมายเหตุ: หากคุณเห็นคะแนนของฉันเพิ่มขึ้นอาจเป็นเพราะฉันพบข้อบกพร่องเล็กน้อย


มากกว่าความท้าทายของรหัสมากกว่าการเล่นกอล์ฟรหัส แต่ยังคง 4872 * 0.8 = 3897,6
กำหนด

3

เสียงกระเพื่อมสามัญ 868 ไบต์ * 0.85 = 737.8

มันเป็นการโกงที่จะใช้ Lisp กับ Lisp หรือไม่? ยังมีอีกหลายอย่างที่ต้องปรับปรุงที่นี่

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

พิมพ์ E ในกรณีที่เกิดข้อผิดพลาดในอินพุต ตัวอย่างการวิ่ง:

$ 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
ตราบใดที่มันไม่ใช่ฟังก์ชั่น eval ...
กำหนด

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

ค่อนข้างเป็นวิธีการแฮ็ก สิ่งนี้จัดเก็บทุกอย่างเป็นสตริงในรูปแบบเอาต์พุตที่พร้อมใช้งาน - ชนิดของพวกเขาสามารถแยกความแตกต่างด้วยตัวอักษรตัวแรกของพวกเขา - 0..9สำหรับตัวเลข(สำหรับรายการtหรือfบูลีนและทุกอย่างอื่นสำหรับฟังก์ชั่น

เพื่อเรียกใช้rฟังก์ชั่น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.