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


17

K เป็นภาษาโปรแกรมในตระกูล APL ที่ออกแบบโดย Arthur Whitney ในขณะที่ล่ามอย่างเป็นทางการเป็นแบบโอเพ่นซอร์สและเชิงพาณิชย์คุณสามารถดูรุ่นทดลองใช้ที่มีพื้นที่ทำงาน 32 บิตของพื้นที่แอดเดรส (ซึ่งไม่น่าจะมีปัญหาสำหรับโค้ดกอล์ฟ) ที่เว็บไซต์Kx Systems รุ่นนี้รวมเป็นส่วนหนึ่งของฐานข้อมูล kdb + เป็นที่รู้จักกันเรียกขานว่า "K4" นอกจากนี้ยังมีการใช้งาน K เปิดแหล่งที่มาอยู่รวมทั้งโคซึ่งจะขึ้นอยู่กับ K3 และล่ามของตัวเองที่เรียกว่าตกลงซึ่งจะขึ้นอยู่กับ K5 และมีเบราว์เซอร์ REPL

Kx Systems มีวิกิที่มีข้อมูล K4 / kdb + / Q และหน้า Kona GitHub ยังมีชุดเอกสารอ้างอิงที่ยอดเยี่ยมอีกด้วย ฉันเริ่มเขียนคู่มือสำหรับ oK / k5 ซึ่งอาจเป็นข้อมูลอ้างอิงที่มีประโยชน์

เช่นเดียวกับJและ APL K เป็นภาษาที่กระชับและทรงพลังและสามารถแสดงให้เห็นได้ดีในการเล่นกอล์ฟ โปรดแบ่งปันเคล็ดลับกลอุบายและสำนวนที่คุณค้นพบและถ้าคุณยังไม่ได้ลอง K ก่อนลองพิจารณา! โพสต์หนึ่งเคล็ดลับต่อคำตอบโปรด!

คำตอบ:


5

โทรหา Dyad

สมมติว่าคุณมีฟังก์ชัน dyadic (2 อาร์กิวเมนต์) f:

f: {x+2*y}

ปกติแล้วคุณจะเรียกมันว่า:

f[3;47]

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

f[3]47

การทำงานเช่นเดียวกันสำหรับการจัดทำดัชนีอาร์เรย์:

  z: (12 17 98;90 91 92)
(12 17 98
 90 91 92)

  z[1;2]
92

  z[1]2
92

5

การพิมพ์บรรทัดใหม่

หากผลลัพธ์ของคุณต้องมีการขึ้นบรรทัดใหม่คุณอาจถูกล่อลวงให้ทำสิ่งนี้:

`0:whatever,"\n"

อย่า K2 (และเวอร์ชันอื่น ๆ น่าจะมีคุณสมบัติ) ซึ่งคุณสามารถพิมพ์รายการบรรทัด:

  `0:("abc";"def")
abc
def

ดังนั้นหากคุณต้องการเพิ่มบรรทัดใหม่ให้กับเอาต์พุตให้ทำดังนี้

`0:,whatever

3

ช่วง

โดยปกติหากคุณต้องการสร้างเวกเตอร์ของตัวเลขเรียงลำดับที่คุณใช้!:

  !5
0 1 2 3 4

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

  10+!5
10 11 12 13 14

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

  &10 5
0 0 0 0 0 0 0 0 0 0 1 1 1 1 1
  &&10 5
10 11 12 13 14

สำหรับลำดับที่เติบโตช้าลงให้พิจารณาการรวม "โดย" กับ "ใช้":

  5#2
2 2 2 2 2
  &5#2
0 0 1 1 2 2 3 3 4 4

หากคุณต้องการสร้างช่วงของทวีคูณคุณสามารถคูณผลลัพธ์!หรือคุณสามารถสแกน ( \) รายการสำเนาขนาดขั้นตอน:

  2*!5
0 2 4 6 8
  +\5#2
2 4 6 8 10

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


2

ปลดเปลื้องจากสายมีราคาแพง เพียงใช้ eval นี้:

0.0$a

สามารถเป็นเพียงแค่นี้:

. a

ใน K5 มันสั้นลงหนึ่งไบต์:

.a

2

แต่ละขวา

บางครั้งคุณอาจพบว่าตัวเองเขียน (หรือมาถึงโดยลดความซับซ้อน) การแสดงออกวงเล็บที่ใช้ผ่านแต่ละ monad:

  (2#)'3 4 5
(3 3
 4 4
 5 5)

สั้นลงหนึ่งตัวเพื่อแปลงรูปแบบนี้เป็นแอปพลิเคชันของแต่ละด้านขวา:

  2#/:3 4 5
(3 3
 4 4
 5 5)

1

วงจรเรียงสับเปลี่ยน

Dyadic !ใน K3 / K4 คือ "หมุน":

  2!"abcd"
"cdab"
  -1!"abcd"
"dabc"

เมื่อ "scan" ( \) ให้มาพร้อมกับ monadic verb มันจะทำหน้าที่เป็นโอเปอเรเตอร์จุดคงที่ ใน K ตัวดำเนินการจุดคงที่จะใช้กริยากับค่าซ้ำ ๆ จนกระทั่งค่าเริ่มต้นถูกตรวจทานอีกครั้งหรือค่าหยุดการเปลี่ยนแปลง การผสมผสานการหมุนกับการสแกนแบบจุดคงที่นั้นเป็นวิธีที่สะดวกมากในการคำนวณชุดวงจรเรียงสับเปลี่ยนของรายการ:

  ![1]\1 2 4 8
(1 2 4 8
 2 4 8 1
 4 8 1 2
 8 1 2 4)

คุณสามารถแกง!ด้วยวงเล็บหรือสร้างวงเล็บเพื่อสร้างคำกริยา(1!):

![1]\
(1!)\

(โปรดทราบว่า1!\มีพฤติกรรมที่แตกต่างกันโดยสิ้นเชิง!) แต่ละสิ่งเหล่านี้มีความยาวเท่ากัน แต่ในอดีตอาจเป็นที่ต้องการมากกว่าหากการหมุนของการหมุนเป็นอย่างอื่นที่ไม่ใช่ 1; ในกรณีนี้วงเล็บจะคั่นนิพจน์ย่อยในวงเล็บ "ฟรี"

ดังตัวอย่างต่อไปนี้เป็นโปรแกรมสั้น ๆ ที่ทดสอบด้วยแรงเดรัจฉานว่าสตริง x มีซับสตริง y (cyclically!) หรือไม่:

{|/(y~(#y)#)'![1]\x}

ผู้ใช้ K5 ระวัง! K5 เปลี่ยนความหมายของ dyadic !ดังนั้นเทคนิคนี้จึงไม่ง่ายนัก มันจะทำงานได้ตามที่คาดไว้ใน Kona


1

หลีกเลี่ยงเงื่อนไข

K มีโครงสร้างแบบมีเงื่อนไข ( :[) ซึ่งเทียบเท่ากับ Lisp-style cond:

:[cond1;result1; cond2;result2; cond3;result3; default]

คุณสามารถมีเงื่อนไขได้มากเท่าที่คุณต้องการและหากไม่ตรงกับค่าเริ่มต้นจะถูกส่งกลับ

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

พิจารณาโปรแกรมfizzbuzz ที่น่าอับอาย เขียนในรูปแบบการเขียนโปรแกรมที่จำเป็นธรรมดาเราอาจไปกับ:

{:[~x!15;"FizzBuzz";~x!3;"Fizz";~x!5;"Buzz";x]}'1+!100

มีการทำซ้ำเล็กน้อยในการทดสอบการหาร วิธีการที่แตกต่างกันยอมรับว่ามี 4 กรณี (ตัวเลข, หารด้วย 3 เท่านั้น, หารด้วย 5 เท่านั้น, หารด้วย 3 และ 5) และพยายามคำนวณดัชนีโดยตรงซึ่งเลือกหนึ่งในกรณีเหล่านี้จากรายการ:

{(x;"Fizz";"Buzz";"FizzBuzz")@+/1 2*~x!/:3 5}'1+!100

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

{(x;4#t;4_ t;t:"FizzBuzz")@+/1 2*~x!/:3 5}'1+!100

ตอนนี้เราได้บันทึกตัวละคร 5 ตัวโดยรวมแล้ว ตัวอย่างนี้ทำงานได้ดีกว่าแม้ใน k5 เนื่องจากเรามี "แพ็ค" เกินพิกัดสำหรับ/จัดการขั้นตอนการคูณด้วยเวกเตอร์ของสัมประสิทธิ์และการรวม:

{(x;4_t;4#t;t:"FizzBuzz")@2 2/~3 5!\:x}'1+!100

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

{("AEIOU",x)"aeiou"?x}'

กับหนึ่งใน:

{t:"aeiou"?x;:[t<5;"AEIOU"t;x]}'
{:[~4<t:"aeiou"?x;"AEIOU"t;x]}'

(ฉันรู้ว่าฉันอ่านอะไรดีด้วย!)

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