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


15

แกลบเป็นภาษากอล์ฟค่อนข้างใหม่สร้างโดยผู้ใช้ PPCG สิงห์และZgarb มันเริ่มมีการแข่งขันมากขึ้นและมักจะอยู่ใกล้หรือแม้กระทั่งการตีภาษาที่รู้จักกันว่าสั้นมากเช่นวุ้นและ 05AB1E

ลองทำรายการเทคนิคการตีกอล์ฟที่ค่อนข้างเฉพาะเจาะจงกับ Husk เช่นเคยโปรดโพสต์หนึ่งเคล็ดลับต่อคำตอบ



1
@tallyhumanhuman คำตอบแรกยังคงไม่ใหม่
H.PWiz

คำตอบ:


10

ใช้ค่าส่งคืนจากเพรดิเคต

ใน Husk ฟังก์ชั่นที่ทดสอบอินพุตของพวกเขาสำหรับคุณสมบัติบางอย่างมักจะส่งคืนผลลัพธ์ที่มีความหมายในกรณีความจริงเนื่องจากจำนวนเต็มบวกใด ๆ คือความจริง

ตัวอย่าง:

≠  Numbers: Absolute difference
   Chars:   Absolute difference of code points
   Lists:   First Index where the differ

Comparisons <, >, ≤, ≥:

For strict comparisons:
Numbers,Chars:  max 0 (the appropriate difference¹)
Lists: The first index where the comparison between the two lists is true

For non-strict comparisons:
Numbers,Chars: max 0 (the appropriate difference + 1)
Lists: Either the result of the strict comparison or, if they are equal,
       the length of the list + 1

ṗ  Index into the list of prime numbers

V  The index of the first element for which the condition is true

€  The first index of that element/substring in the list

£  Works like €

&  Given two arguments of the same type will return the second argument if false,
   otherwise will return the first argument

|  Given two arguments of the same type will return the second argument if true,
   otherwise will return the first argument

¦  Return the quotient if divisibility holds

Λ,E,Ë  Will all return length+1 in truthy cases

Char predicates:
□,±,√,D,½  will each return the codepoint of its argument on truthy cases

¹ ความแตกต่างที่เหมาะสมหมายถึงความแตกต่างของจุดสำหรับตัวอักษร นอกจากนี้ยังอ้างถึงลำดับอาร์กิวเมนต์ เช่นสำหรับ<x yจะเป็นx-y


7

ใช้ป้ายกำกับบรรทัดที่ล้น

ดังที่คุณอาจทราบอยู่แล้วว่า [₀-₉]+|[₀-₉]regex สำหรับไวยากรณ์ในการโทรสายที่แตกต่างจากที่คุณอยู่ในปัจจุบัน

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

ตารางฟังก์ชั่น:

+----------+----------+
|Index     |Function  |
+----------+----------+
|1         |´ (argdup)|
+----------+----------+
|2         |` (flip)  |
+----------+----------+
|3         |m (map)   |
+----------+----------+
|4         |z (zip)   |
+----------+----------+
|5         |S (hook)  |
+----------+----------+

บรรทัดในรหัสของคุณมีป้ายกำกับที่มีดัชนีอิงดัชนี 0 รายการจากบนลงล่าง หากM <Nที่MคือฉลากและNคือจำนวนของเส้นในรหัสของคุณป้ายเพียงแค่แสดงให้เห็นถึงฟังก์ชั่นที่กำหนดไว้ที่เส้นM ถ้าN ≤ M <N * 6มันแสดงถึงฟังก์ชั่นจากตารางข้างต้นที่ดัชนี⌊M function N⌋กับฟังก์ชั่นที่กำหนดไว้ที่บรรทัดM mod Nเป็นอาร์กิวเมนต์แรก ถ้าN * 6 ≤ Mข้อผิดพลาดดัชนีจะเพิ่มขึ้น


5

แลมบ์ดาอาจสั้นกว่าฟังก์ชั่นใหม่

อย่างที่คุณอาจทราบว่าคุณมีโปรแกรมหลายบรรทัดคุณสามารถอ้างถึงบรรทัดที่มีตัวห้อย₀…₉ตัวอย่างเช่นในกรณีของ

f
g

gจะอ้างถึงฟังก์ชั่น ตอนนี้ถ้าคุณใช้อินพุตกับฟังก์ชั่นเสมอg(และใช้มันหลาย ๆ ครั้ง); บางสิ่งเช่นนี้

f₁⁰[...]g₁⁰[...]
h

คุณควรแนะนำแลมบ์ดาเพราะมันช่วยให้คุณประหยัด 1 ไบต์สำหรับการใช้งานแต่ละครั้ง:

λf⁰[...]g⁰[...])h

การย้อนกลับอาจเป็นจริงเช่นกัน

ในกรณีของการ lambdas ตัวอ้างอิง (คนφχψ) มีกรณีพิเศษที่คุณใช้ปัจจัยการผลิตโดยตรงกับฟังก์ชันเวียนในกรณีเหล่านี้คุณก็ยังดีโดยใช้ห้อยแทนการกำหนดแลมบ์ดาใหม่และการใช้


5

การใช้ประโยชน์จาก Γ

การใช้งานหลักของ built-in Γหรือที่เรียกว่าการจับคู่รูปแบบในรายการหรือโครงสร้างรายการคือการแบ่งรายการออกเป็นส่วนหัวและส่วนท้ายและใช้ฟังก์ชันไบนารีกับพวกเขา สิ่งนี้สอดคล้องกับสำนวนรูปแบบการจับคู่ Haskell

f (x : xs) = <something>
f [] = <something else>

ที่<something>อยู่ในการแสดงออกที่มีx, และอาจxs fมีการบรรทุกเกินพิกัด 4 รายการΓซึ่งแต่ละชุดทำงานแตกต่างกันเล็กน้อย

list

มากไปครั้งแรกlistจะใช้เวลาคุ้มค่าและฟังก์ชั่นแบบไบนารีa fส่งคืนฟังก์ชันใหม่ที่รับรายการส่งคืนaหากไม่มีข้อมูลและเรียกfใช้หัวและส่วนท้ายหากไม่มีข้อมูล ตัวอย่างเช่นΓ_1€รับรายการส่งคืน-1ถ้ามันว่างเปล่าและดัชนีการเกิดขึ้นครั้งแรกขององค์ประกอบแรกในหางถ้าไม่

listN

การบรรทุกเกินพิกัดครั้งที่สองlistNคล้ายกับlistยกเว้นว่าaถูกละเว้นและใช้ค่าเริ่มต้นของประเภทส่งคืนแทน ยกตัวอย่างเช่นΓ€เทียบเท่ากับตั้งแต่ค่าตัวเลขเริ่มต้นคือΓ0€0

ในทางปฏิบัติlistNมีการใช้บ่อยกว่าlistเนื่องจากค่าเริ่มต้นไม่เกี่ยวข้องหรือเป็นสิ่งที่คุณต้องการ รูปแบบทั่วไปคือΓ~αβγโดยที่αβγมีสามฟังก์ชัน นี้βไปยังองค์ประกอบแรกและหางและรวมผลกับγ αมันถูกใช้เช่นในคำตอบนี้ รูปแบบอื่น ๆ รวมถึงΓo:αการใช้αกับองค์ประกอบแรกเท่านั้นและΓ·:mαใช้αกับองค์ประกอบทั้งหมดยกเว้นรายการแรก หลังถูกใช้ในคำตอบนี้

listF

การบรรทุกเกินพิกัดครั้งที่สามนั้นเกี่ยวข้องกับอีกเล็กน้อย เช่นเดียวกับlistมันใช้ค่าaและฟังก์ชั่นfและส่งกลับฟังก์ชั่นใหม่gที่ใช้รายการ อย่างไรก็ตามเวลานี้fใช้อาร์กิวเมนต์ของฟังก์ชันพิเศษซึ่งเป็นgตัวเองและสามารถเรียกมันได้บนค่าใด ๆ (รวมถึง แต่ไม่ จำกัด เฉพาะที่ส่วนท้ายของรายการอินพุต) ซึ่งหมายความว่าlistFใช้รูปแบบการเรียกซ้ำทั่วไปในรายการ listFไม่ได้ใช้บ่อยนักเนื่องจากการเรียกซ้ำโดยชัดเจนด้วยlist/ listNมักจะมีความยาวเท่ากันหรือสั้นกว่าดังที่คำตอบนี้

listNF

listNFคือlistFอะไรlistNคือlist: อินพุตaถูกละเว้นและใช้ค่าดีฟอลต์ของชนิดส่งคืนแทน ในสถานการณ์ที่หายากมันอาจสั้นกว่าครึ่งทางขวาตัวอย่างเช่นในคำตอบนี้

เป็นตัวอย่างของเวอร์ชันที่เรียกซ้ำได้Γฟังก์ชันจะΓλ·:o⁰↔สลับรายการตามลำดับก่อน, สุดท้าย, วินาที, วินาที, สองไปจนถึงสุดท้าย, สาม, สามต่อจากนี้และต่อไปเรื่อย ๆ ลองออนไลน์! ฟังก์ชั่นfเป็นแลมบ์ดาที่ชัดเจนλ·:o⁰↔ซึ่งอาร์กิวเมนต์เป็นฟังก์ชั่นทั้งหมด สิ่งที่fไม่สามารถย้อนกลับหางด้วยแล้วเรียกใช้ฟังก์ชันหลักซ้ำด้วยและในที่สุดก็ตรึงกลับหัวด้วยo⁰ ·:แน่นอนว่าΓ·:o₀↔เป็นไบต์ที่สั้นกว่า แต่ไม่สามารถใช้งานได้หากบรรทัดนั้นมีสิ่งอื่นนอกเหนือจากฟังก์ชั่นนี้


3

Combinators สามารถใช้กับฟังก์ชั่นการสั่งซื้อที่สูงขึ้น

สมมติว่าคุณมีรายการจำนวนเต็มXและคุณต้องการนับจำนวนองค์ประกอบทั้งหมดของXที่ใหญ่กว่าความยาว (X) องค์ประกอบที่นับว่าตอบสนองคำกริยาจะทำกับฟังก์ชั่นการสั่งซื้อที่สูงขึ้น#แต่ที่นี่วินิจฉัย (เป็นขนาดใหญ่กว่าความยาว (X) ) ขึ้นอยู่กับX วิธีการแก้ปัญหาคือการใช้ combinator กับ#และฟังก์ชั่นo>Lที่ตรวจสอบว่ารายการสั้นกว่าตัวเลขหรือไม่ ในฟังก์ชั่นṠ#o>Llist Xจะถูกส่งไปยังo>Lฟังก์ชั่นที่นำไปใช้บางส่วนจะถูกส่งไปยัง#และXจะถูกกำหนดให้#เป็นอาร์กิวเมนต์ที่สอง

โดยทั่วไปถ้าαเป็นฟังก์ชันที่มีลำดับสูงกว่าฟังก์ชันβเลขฐานสองและγฟังก์ชัน unary Ṡαβจะเทียบเท่ากับ Haskell pseudocode

\x -> α (\y -> β x y) x

§αβγ เทียบเท่ากับ

\x -> α (\y -> β x y) (γ x)

และ~αβγเทียบเท่า

\x y -> α (\z -> β x z) (γ y)

ตราบใดที่ประเภทตรงกัน

เป็นอีกตัวอย่างที่เป็นรูปธรรม§►δṁ≠Pค้นหาการเปลี่ยนแปลงของรายการXที่เพิ่มผลรวมของความแตกต่างสัมบูรณ์ให้มากที่สุดกับค่าที่สอดคล้องกันของX ( δṁ≠ซิปสองรายการโดยใช้ความแตกต่างแบบสัมบูรณ์และรับผลรวม)


3

ค่าเริ่มต้นของ Husk

Husk นั้นไม่เข้มงวดเท่ากับ Haskell ที่ซึ่งคุณประสบปัญหาเมื่อเช่นคุณพยายามที่จะรับ lastองค์ประกอบของรายการที่ว่างเปล่า เพื่อให้บรรลุนี้จะใช้ค่าที่กำหนดไว้ล่วงหน้านี่คือรายการของค่าเริ่มต้น maxima และ minima:

.------------------------------------.---------------.----------.-------.
|   Type (X and Y are placeholders)  | default (def) |    max   |  min  |
|------------------------------------|---------------|----------|-------|
|       Character (C)                |      ' '      | \1114111 | \NUL  |
|       Numbers   (N)                |       0       |   Inf    | -Inf  |
|       List of X (LX)               |      []       |  ∞ max   |   []  | *
|       Function :: X -> Y           | const (def Y) |   n/a    |  n/a  |
'------------------------------------'---------------'----------'-------'

* ที่นี่∞ควรแสดงรายการอนันต์ของค่าสูงสุดที่สอดคล้องกัน (ดูตัวอย่างด้านล่าง)

บันทึก:สำหรับ tuples (X, Y) มันจะใช้ค่าสำหรับแต่ละองค์ประกอบแยกจากกัน


เมื่อพวกเขาจะใช้

ขณะที่ maxima และ minima ใช้สำหรับ▲▼รายการที่ว่างเปล่าเท่านั้น (ตัวอย่างเช่นhusk -u "▼" "[]:LLN"จะส่งคืนรายการที่ไม่มีที่สิ้นสุดของInf ) ค่าเริ่มต้นจะถูกใช้ในบางสถานที่:

  • พับรายการที่ว่างเปล่าโดยไม่ต้องให้คุณค่ากับตัวเอง (Fและ)
  • การเติมค่าเริ่มต้น (ด้วย Θ )
  • เมื่ออ่าน (r ) ล้มเหลว
  • รับองค์ประกอบแรก / สุดท้าย (←→ ) หรือการจัดทำดัชนีเป็นหนึ่ง ( !)
  • การจับคู่รูปแบบ (Γ ) ในรายการว่าง
  • ใช้หรือในรายการที่ว่างเปล่า
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.