เคล็ดลับสำหรับการเล่นกอล์ฟใน Racket / Scheme


15

สิ่งใดที่คุณมีเคล็ดลับทั่วไปสำหรับการเล่นกอล์ฟในแร็กเก็ต / โครงการ ? ฉันกำลังมองหาแนวคิดที่สามารถนำไปใช้กับปัญหาเกี่ยวกับการเขียนโค้ดกอล์ฟโดยทั่วไปซึ่งอย่างน้อยค่อนข้างเฉพาะกับ Racket / Scheme (เช่น "ลบความคิดเห็น" ไม่ใช่คำตอบ)


ฉันทราบSchemeและRacket (เดิมชื่อ PLT Scheme) เป็นภาษาที่แตกต่างกันในทางเทคนิค แต่ค่อนข้างคล้ายกันในหลาย ๆ ทางและรหัสมาก (ฉันสงสัยว่า) จะทำงานส่วนใหญ่ตามที่ตั้งใจไว้ในทั้งสอง หากเคล็ดลับของคุณใช้กับภาษาใดภาษาหนึ่งดังกล่าวข้างต้นให้สังเกตเช่นนั้น

คำตอบ:


3

การแสดงออก'x, `x, ,xการ,@xโดยอัตโนมัติขยายตัวออกไป(quote x), (quasiquote x), (unquote x)และ(unquote-splicing x)ตามลำดับ นี่เป็นการเปลี่ยนแปลงทางวากยสัมพันธ์อย่างแท้จริงและสามารถนำไปใช้ได้ทุกที่ สิ่งนี้ให้สัญกรณ์ที่สะดวกสำหรับฟังก์ชันหนึ่งตัวแปร:

; Defining a function:
(define ,x (+ x x))
; Calling a function:
(display ,2)

ซึ่งขยายเป็น

; Defining a function:
(define (unquote x) (+ x x))
; Calling a function:
(display (unquote 2))

ฉันไม่แน่ใจว่า semantics สำหรับแชโดว์คำหลักประโยคเช่นquoteหรือquasiquoteตัวแปรที่ถูกผูกไว้ถึงแม้ว่ารหัสเช่นด้านบนทำงานในล่ามที่ฉันทดสอบบนและunquote-splicingน้อยกว่าอุดมคติเนื่องจากมีตัวย่อสองตัวอักษร แต่unquoteเป็นไวยากรณ์เสริมที่มีตัวย่อตัวเดียวและเหมาะอย่างยิ่งสำหรับการแฮ็คนี้


8

ใน แร็กเก็ต , λและlambdaมีความหมายเหมือนกันคำหลักในการสร้างฟังก์ชั่นที่ไม่ระบุชื่อ แต่λคือ 2 ไบต์ที่lambda6

ในSchemeไม่มีคำหลักดังกล่าวλและคุณติดอยู่lambdaและคุณติดอยู่กับ



5

เมื่อใช้งานแร็กเก็ตให้ผูกตัวแปรที่ใช้λเพื่อกำจัดจำนวนไบต์ที่น้อยลง ในโครงการ ,lambdaทำเคล็ดลับนี้ไม่ได้บังคับว่าถ้าผู้ใดมีผลผูกพันสี่หรือมากกว่าตัวแปร

ตัวอย่าง: หนึ่งตัวแปรบันทึกได้ 2 ไบต์บนlet/define

(define n 55)(* n n) ; 20 bytes

(let([n 55])(* n n)) ; 20 bytes

((λ(n)(* n n))55) ; 18 bytes

ฉันจะไม่เรียกสิ่งนั้นที่มีผลผูกพัน คุณกำลังใช้ฟังก์ชั่นที่แตกต่างกัน ในบางกรณีการใช้ฟังก์ชันที่ไม่ระบุชื่อจะสั้นกว่าการผูกตัวแปร
Michael Vehrs

ฉันไม่แน่ใจว่าความคิดเห็นของคุณเกี่ยวข้องกับคำศัพท์ทั่วไปอย่างไร ใช้ในรูปแบบวงกลมหรือไม่ ผมสามารถมั่นใจได้ทั้งสองวิธีมีผลผูกพันตัวแปรขอบเขตคำศัพท์และมักจะถูกนำมาใช้ในแง่ของlet lambda
Winny

5

ในแร็กเก็ต , requireรูปแบบสามารถมีข้อโต้แย้งหลาย

(require net/url net/uri-codec)

เป็นวิธีที่สั้นกว่า

(require net/url)(require net/uri-codec)

ฉันไม่ค่อยรู้เรื่องSchemeมากนักแต่ดูเหมือนว่ามันจะไม่มีrequirebuiltin


5

ใช้คำพ้องความหมายที่สั้นกว่า

มีกระบวนการหลายอย่างใน Racket ที่มีเวอร์ชันสั้นกว่าซึ่งส่วนใหญ่เทียบเท่า (โดยทั่วไปจะไม่เทียบเท่า: ตัวอย่างเช่น(car (cons 1 2))ทำงานที่ไหน(first (cons 1 2))ล้มเหลว แต่คุณสามารถทำการทดแทนหากคุณรู้ว่าพวกเขาเป็นคำพ้องความหมายในกรณีของคุณ)

รายการนี้อาจไม่สมบูรณ์: ฉันอาจไม่รู้เกี่ยวกับสิ่งต่าง ๆ ที่อาจเกิดขึ้นในรายการนี้

  • (= a b) แทน (equal? a b)เมื่อเปรียบเทียบตัวเลข
  • '(1 2) แทน (list 1 2)แทน
  • car, cadr, cdrสำหรับfirst, secondและrestและ
  • null? แทน empty?
  • modulo แทน remainderเมื่อโมดูลัสเป็นบวก
  • floorแทนที่จะtruncateเป็นข้อโต้แย้งเมื่อมันเป็นบวก

4

ละเว้นช่องว่างที่ไม่จำเป็น

นี่ถือได้ว่าเป็น "เคล็ดลับเล็กน้อย" แต่มันจะต้องชี้ให้เห็นที่ไหนสักแห่ง

เมื่อใดก็ตามที่คุณอ่านรหัสแร็กเก็ตที่เขียนโดยคนปกติ (เช่นในเอกสารประกอบของแร็กเก็ต ) มันจะมีช่องว่างทั้งหมดที่ใส่: ตัวอย่างเช่น

(append (list 1 2) (list 3 4) (list 5 6) (list 7 8))

ในความเป็นจริงเนื่องจาก(และ)ไม่สามารถเป็นส่วนหนึ่งของชื่อตัวแปรเราสามารถลบช่องว่างทั้งหมดรอบตัวพวกเขาและไม่ทำให้เกิดความกำกวม (และที่สำคัญกว่านั้นคือยังคงได้รับรหัสที่ถูกต้อง) ดังนั้นการแสดงออกข้างต้นสามารถแทน:

(append(list 1 2)(list 3 4)(list 5 6)(list 7 8))

2

เคล็ดลับต่อไปนี้สำหรับแร็กเก็ต :

อาร์กิวเมนต์เริ่มต้น

มีประโยชน์อย่างยิ่งสำหรับการสร้างชื่อแทนสำหรับชื่อฟังก์ชันที่ใช้บ่อย

สมมติว่า Golf ช่วยให้คุณสามารถเขียนฟังก์ชั่นที่ใช้การโต้แย้งและสมมติว่าคุณต้องใช้reverseมาก คุณจะเริ่มต้นด้วยสิ่งที่ชอบ:

(λ(x) ... reverse ... reverse ... reverse ...

คุณสามารถรับอาร์กิวเมนต์เพิ่มเติมแทนโดยใช้ชื่อที่สั้นกว่าreverseและตั้งค่าเริ่มต้นเป็นreverse:

(λ(x[r reverse]) ... r ... r ... r ...

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

match

อันนี้ค่อนข้างยากที่จะสรุปในโพสต์เล็ก ๆ ดังนั้นให้อ่านบนRacket Docsสำหรับเอกสารนี้ สรุปmatchช่วยให้คุณสามารถแยกองค์ประกอบและลำดับขององค์ประกอบในลำดับที่แน่นอนจากรายการและไวยากรณ์ quasiquote ช่วยให้คุณสามารถเย็บรายชื่อที่ถูกตัดกลับมารวมกัน:

(match (range 10)
 [`(,xs ... 3 ,ys ... 6 ,zs ...)
  `(,@(map f xs) 3 ,@(map f ys) 6 ,@(map f sz))]
 ...

นอกจากนี้ยังช่วยให้คุณสามารถทำงานกับนิพจน์ทั่วไปและทำการคำนวณเพิ่มเติมในกลุ่มผลลัพธ์หลังจากนั้น

ตั้งชื่อ let

ดูไวยากรณ์ที่มีชื่อที่นี่let proc-id ...ที่นี่

สิ่งนี้ช่วยให้คุณสามารถเขียนฟังก์ชั่นวนซ้ำที่เรียกได้ทันทีโดยไม่ต้อง defineเรียกใช้ฟังก์ชั่นจริงหรือหลังจากเรียกใช้งานจริง

สิ่งที่ต้องการ:

(define (fib i)
  (if (< i 2) i
      (+ (fib (- i 1)) (fib (- i 2)))))
(fib 10)

สามารถย่อให้เหลือ:

(let fib {[i 10]}
  (if (< i 2) i
      (+ (fib (- i 1)) (fib (- i 2)))))


สุดท้ายนี้คือโง่ แต่ผมยังไม่ได้รับสามารถที่จะใช้เคล็ดลับเล็ก ๆ น้อย ๆ นี้ได้ทุกที่เพื่อให้ห่างไกล:
(apply map list matrix)ใช้เวลา transpose ของmatrixที่บางรายการสี่เหลี่ยมของรายการเช่นmatrix แจ้งให้เราทราบหากนี่พิสูจน์ได้ว่ามีประโยชน์'((1 2 3) (a b c))


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