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


28

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

คำตอบ:


23

แก้ไข : สำหรับคนที่อ่านข้อความนี้ที่ไม่รู้จัก APL เลย แต่ต้องการนำมันไปใช้การเรียนรู้ Dyalog APLเป็นทรัพยากรที่ดีมาก

  1. การประเมินผลจากขวาไปซ้ายอย่างเคร่งครัด ซึ่งรวมถึงการตั้งค่าตัวแปรดังนั้นใช้ประโยชน์จากมัน

    2+a, 1+a←1 -> 3 4

    aมีการตั้งค่า1, 1+aประเมิน2, a,2ประเมิน1 2และประเมิน2+1 23 4

  2. เช่น C, สามารถใช้ร่วมกับฟังก์ชั่นคือ a +← 3ซึ่งแตกต่างจาก C นี้เป็นทั่วไป: foo F← barชุดไปfoo F barค่อนข้างbarไม่สมF barเหตุผลในฐานะที่เป็นสำนวนที่ผลตอบแทนนี้ไม่ใช่

    มันทำงานได้กับฟังก์ชั่นที่ไม่ระบุชื่อด้วย:

          a←0
          a+←3 ⋄ a
    3
          a+←3 ⋄ a
    6
          a { ⍵/'!' } ←4 ⋄ a
    !!!!
    
  3. คุณสามารถกำหนดให้กับอาเรย์: A[3]←8อย่างที่คุณคาดหวัง แต่คุณยังสามารถกำหนดหลายรายการพร้อมกันได้: A[3 5 6]←9 1 4หรือแม้กระทั่งA[3 5 6]←9ตั้งค่าทั้งหมดให้เป็นรายการเดียวกัน แน่นอนคุณสามารถเพิ่มฟังก์ชั่นที่นี่ด้วย ฟังก์ชั่นจะถูกนำไปใช้กับแต่ละองค์ประกอบแยกกันเช่นถ้าคุณทำ

  4. เป็นเพื่อนของคุณแม้ว่าเขาจะดูไม่ค่อยมีความสุขกับมันก็ตาม

    1. ถ้าFเป็น dyadic, dyadic สวิทช์ขัดแย้ง: <->a F b b F⍨ aสิ่งนี้มีประโยชน์เมื่อเล่นกอล์ฟเพราะสามารถช่วยให้คุณไม่ต้องใช้เครื่องมือจัดฟัน:

      (F G H x) K y      <->     y K⍨ F G H x
      

      สิ่งนี้จะเปลี่ยนลำดับการประเมินผลเนื่องจากมือขวาจะถูกประเมินก่อนทางซ้ายเสมอ

    2. ถ้าFเป็น dyadic monadic จะใช้อาร์กิวเมนต์เดียวกันกับทั้งสองด้านของฟังก์ชัน:

            5⍴5
      5 5 5 5 5
            ⍴⍨5
      5 5 5 5 5
      

      อาร์กิวเมนต์จะถูกประเมินเพียงครั้งเดียว นี้โดยเฉพาะอย่างยิ่งมีประโยชน์กับผลิตภัณฑ์ด้านนอกคือเพื่อเปรียบเทียบแต่ละค่าในอาร์เรย์ที่มีค่าอื่น ๆ ในอาร์เรย์เดียวกันคุณสามารถใช้แทนต้องทำอย่างไร∘.=⍨x∘.=x←(whatever)

    3. ถ้าFเป็น monadic ไม่ทำอะไรเลย แต่แยกฟังก์ชันออกจากอาร์กิวเมนต์ ดังนั้นจึงยังสามารถช่วยให้คุณประหยัดได้หากฟังก์ชันซับซ้อน:

            {⍵+3}⍣5 6
            ∇{⍵+3}              
           ∇ ⍣ 5 6              
            ({⍵+3}⍣5)6
      21
            {⍵+3}⍣5⍨6
      21
      
  5. เรียนรู้สำนวน! จากนั้นเล่นกอล์ฟสำนวน ตัวอย่างเช่น:

    ((((1↑⍴X),⍴Y)↑X)^.=Y)⌿X
    

    สามารถเปลี่ยนเป็นกลไก:

    X⌿⍨Y^.=⍨X↑⍨(1↑⍴X),⍴Y
    

    แล้วต่อไปเป็น:

    X⌿⍨Y^.=⍨X↑⍨(⊃⍴X),⍴Y
    

    (แรก) เทียบเท่ากับ1↑(รับหนึ่ง) ในกรณีนี้ และอาจเป็นไปได้:

    X⌿⍨Y^.=⍨X↑⍨(≢X),⍴Y
    

    (tally) เทียบเท่ากับ⊃⍴(องค์ประกอบแรกของรูปร่าง) สำหรับทั้งหมดยกเว้นสเกลาร์


มีวิธีรับใบอนุญาตฟรีข้างรุ่นราสเบอร์รี่ pi หรือไม่?
Fabinout

วิธีการทางกฎหมายเพื่อให้ได้ชัด
Fabinout

2
@Fabinout: ที่ dyalog.com คุณสามารถดาวน์โหลดเวอร์ชัน Windows ได้ฟรี คลิก "Download Zone" จากนั้นคลิก "Unregistered Download" มันจะดุด่าให้คุณลงทะเบียน แต่อย่างอื่นมันทำงานได้อย่างสมบูรณ์และฟรีและถูกกฎหมาย หากคุณเป็นนักเรียนคุณสามารถรับเวอร์ชันปกติได้ฟรีโดยกรอกแบบฟอร์ม หากคุณไม่ได้อาศัยอยู่ในประเทศที่พวกเขาทำลายชีวิตของคุณเพราะการละเมิดลิขสิทธิ์คุณก็รู้ว่าต้องทำอะไร
marinus

นอกจากนี้ยังมี Nars2000 การใช้งานโอเพ่นซอร์สที่มีคุณสมบัติมากกว่า Dyalog (และข้อบกพร่องบางอย่าง) คุณสมบัติบางอย่างมีประโยชน์สำหรับการเล่นกอล์ฟเช่นฟังก์ชั่นหมายเลขเฉพาะหรือมัลติเซ็ต
Tobia

1
มี GNU APL
M. Alaggan

14

รถไฟ

A(f g h)B      ←→  (A f B)g A h B  ⍝ fork
 (f g h)B      ←→  (  f B)g   h B  ⍝ fork
A(  g h)B      ←→         g A h B  ⍝ atop
 (  g h)B      ←→         g   h B  ⍝ atop
 (A g h)       ←→  ({A} g h)       ⍝ "Agh" fork
 (f g h k)     ←→  (f (g h k))     ⍝ 4-train
 (f g h k l)   ←→  (f g (h k l))   ⍝ 5-train, etc
 (f g h k l m) ←→  (f(g h(k l m))) ⍝ groups of 3 from the right, last could be 2
  f∘g B        ←→    f g B         ⍝ "compose" operator, useful in trains
A f∘g B        ←→  A f g B

นั่นหมายความว่าเพื่อผู้อ่านในอนาคตเราไม่ควรบอก Oberon ว่าจะย่อให้สั้นลงได้อย่างไร
อดัม

ไม่ทำตามปกติบน PPCG ฉันจะลบบรรทัดนั้นหลังจากที่นิพจน์มาถึง (สิ่งที่ฉันเชื่อว่าเป็น) ที่สั้นที่สุด เป็นการออกกำลังกายที่ง่าย - ฉันไม่คิดว่าคุณจะได้ประโยชน์จากมันเป็นการส่วนตัว
ngn

ฉันสามารถทำได้ถึง 16 แต่ฉันไม่ได้ใช้เคล็ดลับใด ๆ ของคุณดังนั้นฉันอาจจะออกไป
อดัม

@ Adámคุณกำลังใช้รถไฟ :) ของฉันคล้ายกัน แต่นานกว่านั้นเพราะฉันไม่ได้คิดถึง⎕ML
ngn

ไม่ใช่ "กลุ่ม 3 จากขวา " ใช่หรือไม่
อดัม

7

เทคนิคในการจัดการกับ/และในรถไฟ

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

ใช้1∊แทน monadic ∨/หรือ∨⌿ในอาร์เรย์บูลีน

ภารกิจ: รับสตริง A และ B ที่มีความยาวเท่ากันสองสตริงส่งคืน 2 หากอักขระที่เกี่ยวข้องของ A และ B เท่ากับ 0 มิฉะนั้น เช่นA←'abc'และB←'def'ให้0และA←'abc'และช่วยให้B←'dec'2

วิธีการแก้ปัญหา dfn อาจเป็นA{2×∨/⍺=⍵}Bแต่คุณต้องการที่จะสั้นลงโดยไปโดยปริยาย A(2×∨/=)Bไม่ได้ไปทำงานเพราะกฎของการสร้างรถไฟแยกนี้เป็นแต่คุณต้องการ2 (× ∨/ =)2 × (∨/=)

สังเกตว่า∨/หรือ∨⌿บนเวกเตอร์บูลีน ( ∨/,หรือ∨⌿,สำหรับอาร์เรย์ยศสูงกว่า) ถามว่ามีใด ๆ 1 ในปัจจุบันคือเพื่อให้เราสามารถเขียนรถไฟของเราเป็น1∊2×1∊=

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

ใช้1⊥แทน monadic +/หรือ+⌿

ภารกิจ: รับรายการลิสต์ L และดัชนี N กลับมาที่ผลรวมของรายการ Nth สามครั้ง เช่นL←(3 1 4)(2 7)และช่วยให้N←124

วิธีการแก้ปัญหา dfn อาจเป็นN{3×+/⍺⊃⍵}Lแต่คุณต้องการที่จะสั้นลงโดยไปโดยปริยาย N(3×+/⊃)Lไม่ได้ไปทำงานเพราะกฎของการสร้างรถไฟแยกนี้เป็นแต่คุณต้องการ3(× +/ ⊃)3 × (+/⊃)

สังเกตว่าการประเมินรายการของตัวเลขในเอกนารี (ฐาน -1) เท่ากับการรวมรายการเนื่องจาก ∑ { a , b , c , d } =  a + b + c + d  = ( a ×1³) + ( b ×1² ) + ( c ×1¹) + ( d ×1⁰) ดังนั้นจึง+/a b c dเป็นเช่นเดียวกับเราและเราสามารถเขียนรถไฟของเราเป็น1⊥a b c d3×1⊥⊃

โปรดทราบว่าข้อโต้แย้งอันดับที่สูงขึ้นเทียบเท่ากับ1⊥+⌿

ใช้f.gแทนf/gด้วยอาร์กิวเมนต์เซนต์คิตส์และเนวิสและ / หรือ

ภารกิจ: กำหนด L รายการและจำนวน N, กลับช่วง 1 อย่างละเอียดจำนวนที่เหลือส่วนที่ต่ำสุดเมื่อองค์ประกอบของการเปิด L โดยแบ่งเป็น NEG L←31 41 59และช่วยให้N←71 2 3

วิธีการแก้ปัญหา dfn อาจเป็นN{⍳⌊/⍺|⍵}Lแต่คุณต้องการที่จะสั้นลงโดยไปโดยปริยาย N(⍳⌊/|)Lไม่ได้ไปทำงานเพราะกฎของการสร้างรถไฟแยกนี้เป็นแต่คุณต้องการ⍳ (⌊/) |⍳ (⌊/|)

ผลิตภัณฑ์ภายในA f.g Bของสเกลาสองฟังก์ชั่นเมื่อข้อโต้แย้งที่มีสเกลาร์และ / หรือพาหะเป็นเช่นเดียวf/ A g Bเพราะทั้งสอง(A[1] g B[1]) f (A[2] g B[2]) f (A[3] g B[3])ฯลฯ ⍳⌊.|ดังนั้นเราจึงสามารถเขียนรถไฟของเราเป็น

โปรดทราบว่าสิ่งนี้ไม่สามารถใช้กับอาร์เรย์อันดับที่สูงกว่าได้

ใช้∊⊆แทน/ด้วยอาร์กิวเมนต์บูลีนด้านซ้ายและเวกเตอร์ขวาอย่างง่าย

ภารกิจ: เมื่อรับรายการ L และตัวเลข N ให้กรองรายการเพื่อให้เหลือเฉพาะตัวเลขที่มากกว่า N เช่นL←3 1 4และช่วยให้N←13 4

วิธีการแก้ปัญหา dfn อาจเป็นN{(⍺<⍵)/⍵}Lแต่คุณต้องการที่จะสั้นลงโดยไปโดยปริยาย N(</⊢)Lไม่ได้ไปทำงานเพราะกฎระเบียบที่มีผลผูกพันจะแยกนี้เป็น(</) ⊢แต่คุณต้องการ/ที่จะเป็นฟังก์ชั่นซ้ำมากกว่าผู้ประกอบการลด

Dyadic ที่มีบูลีนอาร์กิวเมนต์ซ้ายจะแบ่งอาร์กิวเมนต์ที่ถูกต้องตามการรันของ 1s ในอาร์กิวเมนต์ซ้ายโดยปล่อยองค์ประกอบที่ระบุด้วย 0s เกือบจะเป็นสิ่งที่เราต้องการบันทึกสำหรับการแบ่งพาร์ติชันที่ไม่พึงประสงค์ อย่างไรก็ตามเราสามารถกำจัดแบ่งพาร์ทิชันโดยใช้เอก ดังนั้น{(⍺<⍵)/⍵}จะกลายเป็นและทำให้เราสามารถเขียนรถไฟของเราเป็น{∊(⍺<⍵)⊆⍵}∊<⊆⊢

โปรดทราบว่าสิ่งนี้ไม่สามารถใช้กับอาร์เรย์อันดับที่สูงกว่าได้

ใช้0⊥แทน⊢/หรือ⊢⌿ด้วยอาร์กิวเมนต์ตัวเลข

ภารกิจ: กำหนด L รายการและจำนวน N, คูณ N กับองค์ประกอบด้านขวาสุดของขาL←3 1 4และช่วยให้N←28

วิธีการแก้ปัญหา dfn อาจเป็นN{⍺×⊢/⍵}Lแต่คุณต้องการที่จะสั้นลงโดยไปโดยปริยาย N(⊣×⊢/⊢)Lไม่ได้ไปทำงานเพราะกฎของการสร้างรถไฟแยกนี้เป็นแต่คุณต้องการ⊣ (× ⊢/ ⊢)⊣ × (⊢/⊢)

สังเกตว่า0⊥บนอาร์เรย์ตัวเลขเป็นเช่นเดียวกับเพื่อให้เราสามารถเขียนรถไฟของเราเป็น⊢⌿⊣×0⊥⊢

โปรดทราบว่านี่เป็นการเลือกเซลล์หลักสุดท้ายของอาร์เรย์ลำดับที่สูงกว่า


1
บางทีคุณอาจเพิ่มคำตอบแชทนี้ในนี้?
J. Sallé

1
@ เพิ่มJ.Sallé
อดัม

7

ใช้เพื่อรวมการคูณด้วยการเพิ่ม

(a×b)+C  ->  a⊥b,C
(C)+a×b  ->  a⊥b,C
(a×b)-C  ->  a⊥b,-C

สมมติฐาน:

  • aและbเป็นคำศัพท์ที่ไม่ต้องการวงเล็บเพิ่มเติมเมื่อใช้เป็นอาร์กิวเมนต์ซ้าย

  • C เป็นนิพจน์ที่อาจจำเป็นต้องใช้วงเล็บเมื่อใช้เป็นอาร์กิวเมนต์ซ้าย

  • a b C ประเมินเป็นสเกลาร์ตัวเลข


5

ตัวเลขที่ซับซ้อน

มักถูกมองข้ามพวกเขานำเสนอโอกาสที่ยอดเยี่ยมในการตัดทอนการแสดงออกเกี่ยวกับกริดเขาวงกตเศษส่วนหรือรูปทรงเรขาคณิต

0j1⊥¨    0j1⊥   ⍝ pair(s) of reals -> complex
11 9∘○¨  11 9○  ⍝ complex -> pair(s) of reals
|z0-z1          ⍝ distance between two points
0j1×z   0j¯1×z  ⍝ rotate by ±90° around (0,0)
0j1*⍳4          ⍝ the four cardinal directions
+z       -+z    ⍝ reflect across x or y axis
+\0,z           ⍝ sequence of steps -> path
2-/z            ⍝ path -> sequence of steps
0j1⊥¨n-⍳2⍴1+2×n ⍝ lattice centred on (0,0)

4

การสร้างดัชนีความยาวเวกเตอร์โมดูโล

⊃i⌽aมักจะสั้นกว่าไร้เดียงสา⊃a[(≢a)|i]หรือa⊃⍨i|⍨≢a(โดยที่aเวกเตอร์และiเป็นจำนวนเต็มและ⎕ioเป็น 0)

เป็นรูปแบบที่มีประโยชน์เกี่ยวกับเรื่องนี้ (ขอบคุณ EriktheOutgolfer สำหรับการชี้ออก) คือI↑Y⌽⍨I×Xที่Yเป็นกำหนดการ length- บางIเวกเตอร์และXเป็นดัชนีหนึ่งที่เราต้องการที่จะเลือกสำหรับอินสแตนซ์:3↑'JanFeb...Dec'⌽⍨3×month


3

ฟังก์ชั่นคงที่

=⍨และ≠⍨ขอบคุณ ngn

บางครั้งคุณเพียงแค่ต้องการค่าเดียวสำหรับแต่ละองค์ประกอบของรายการ ในขณะที่คุณอาจถูกล่อลวงให้ใช้{value}¨มันสั้นกว่าที่จะใช้value⊣¨ แต่สำหรับค่าทั่วไปบางอย่างคุณสามารถทำให้สั้นลงได้ (โดยใช้⎕IO←0):

¯1กับ ⍬⍸list

0กับ ⍬⍳list

1กับ ⍬⍷list

โปรดทราบว่าสิ่งเหล่านี้ใช้ได้กับรายการเท่านั้น (แม้ว่าอาจซ้อนอยู่) สำหรับอาร์เรย์ระดับสูงคุณสามารถใช้สิ่งต่อไปนี้เพื่อรับ 0s และ 1s ทั้งหมด

1กับ =⍨

0กับ ≠⍨

หากคุณตั้งค่า⎕ML←0ตัวเลขทั้งหมดสามารถทำเป็นศูนย์ (เช่นถ้า) ด้วย:

หากคุณต้องการเพียงหมายเลขเดียวคุณอาจจะสามารถที่จะใช้เอกจะได้รับ 1 หรือ 0 แทนการใช้หรือ1⊣0⊣


" บางครั้งคุณเพียงแค่ต้องการค่าเดียวสำหรับแต่ละองค์ประกอบของรายการ " - มันอาจเป็นสิ่งสำคัญ: เมื่อค่านั้นเป็นองค์ประกอบแรกของรายการคุณสามารถใช้⊣\
ngn

@ngn ฉันจะบอกอย่างนั้นและด้วย/และทำโพสต์ของตนเอง
อดัม

2

ใช้

หลีกเลี่ยงวงเล็บ

(การเดินทาง) สามารถช่วยให้คุณประหยัดไบต์โดยการหลีกเลี่ยงวงเล็บ เมื่อใดก็ตามที่คุณมีฟังก์ชั่นที่ตอบสนองความต้องการอาร์กิวเมนต์ซ้ายเพื่อจะ parenthesised และการโต้แย้งสิทธิไม่ได้คุณสามารถบันทึกไบต์เช่น→(A<B)÷CC÷⍨A<B

สองอาร์เรย์

ผนวกสำเนาของอาร์เรย์ที่จะสิ้นสุดการใช้งานหรือ,⍨A⍪⍨A

ตัวเลขสองเท่า

แทนการใช้2∘×จะเป็นสองเท่าคุณสามารถใช้+⍨เพราะมันจะเพิ่มการโต้แย้งกับตัวเอง: →1+2∘×1++⍨

หมายเลขสแควร์

แทนการใช้2*⍨Yตารางคุณสามารถใช้×⍨Yเพราะมันคูณโต้แย้งกับตัวเอง: →2*⍨A+B×⍨A+B

การเรียงสับเปลี่ยนแบบสุ่ม

?⍨NNจะทำให้คุณมีการเปลี่ยนแปลงแบบสุ่มของความยาว

ประเภทตัวเอง

ค้นหาดัชนีการเกิดขึ้นครั้งแรกของแต่ละเซลล์หลักด้วย ⍳⍨A

นับ 1 ต่อท้ายในเวกเตอร์บูลีน

แทนการ+/∧\⌽Bนับจำนวน 1s ต่อท้ายที่มีอยู่ในคุณสามารถใช้N⊥⍨

องค์ประกอบย้อนกลับ

A f∘g Bเป็นA f g Bแต่ถ้าคุณต้องการใช้(g A) f Bf⍨∘g⍨

ย้อนกลับลด

f/ a1 a2 a3a1 f (a2 f a3)เป็น หากคุณต้องการใช้(a1 f a2) f a3f⍨/⌽

ย้อนกลับการสแกน

f\ A B C
A (A f B) (A f (B f C))เป็น

f⍨/∘⌽¨,\ A B C
A (A f B) ((A f B) f C)เป็น

f⍨\⌽ A B C
((A f B) f C) (B f C) Cเป็น

⌽f/∘⌽¨,\⌽ A B C.
(A f (B f C)) (B f C) Cเป็น


2

ระบุอักขระในสตริงโดยไม่ต้อง ⍳≢

ภารกิจ: รับสองสตริง S และ T แสดงรายการดัชนีการต่อข้อมูล เช่นS←'abcd'และช่วยให้T←'xyz'1 2 3 4 5 6 7

วิธีการแก้ปัญหา dfn อาจเป็นS{⍳≢⍺,⍵}Tแต่คุณต้องการที่จะสั้นลงโดยไปโดยปริยาย ⍳≢,ไม่ได้ไปทำงานเพราะรถไฟแยกกฎจะแยกนี้เป็นแต่คุณต้องการ(⍳)≢(,)(⍳≢),

dyadic กับที่ว่างเปล่าซ้ายอาร์กิวเมนต์อาร์เรย์เกรดตัวละครที่เรียบง่ายตามลำดับปัจจุบันของพวกเขาซึ่งเป็นเช่นเดียวกับ ⍳≢ดังนั้น{⍳≢⍺,⍵} จะกลายเป็นเพื่อให้เราสามารถเขียนรถไฟของเราเป็น{⍬⍋⍺,⍵}⍬⍋,

โปรดทราบว่าวิธีนี้ใช้ไม่ได้กับอาร์เรย์ตัวเลขหรืออาร์เรย์ผสม


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