Lời khuyên cho việc chơi golf ở K


17

K là ngôn ngữ lập trình trong gia đình APL được thiết kế bởi Arthur Whitney. Mặc dù trình thông dịch chính thức là nguồn đóng và thương mại, phiên bản dùng thử với giới hạn không gian làm việc là 32 bit không gian địa chỉ (không gây ra vấn đề cho mã golf) có thể được tìm thấy tại trang web của Kx Systems . Phiên bản này được đóng gói như một phần của cơ sở dữ liệu kdb + được gọi chung là "K4". Ngoài ra còn có các triển khai K nguồn mở có sẵn, bao gồm Kona , dựa trên K3 và trình thông dịch riêng của tôi được gọi là oK , dựa trên K5 và có REPL dựa trên trình duyệt .

Kx Systems có wiki với thông tin K4 / kdb + / Q và trang Kona GitHub cũng có một bộ sưu tập tài liệu tham khảo tuyệt vời . Tôi đã bắt đầu viết một hướng dẫn cho oK / k5 có thể là một tài liệu tham khảo hữu ích.

Giống như J và APL, K là một ngôn ngữ rất ngắn gọn và mạnh mẽ, và thường có thể thể hiện tốt trong môn đánh gôn. Vui lòng chia sẻ mẹo, thủ thuật và thành ngữ bạn khám phá và nếu bạn chưa thử K trước khi xem xét cho nó một vòng quay! Gửi một lời khuyên cho mỗi câu trả lời, xin vui lòng!

Câu trả lời:


5

Gọi một Dyad

Giả sử bạn có hàm dyadic (2-argument) f:

f: {x+2*y}

Bạn thường gọi nó như vậy:

f[3;47]

Bạn có thể lưu một ký tự bằng cách thay vào đó là curry trong đối số thứ nhất và sau đó áp dụng hàm một phần kết quả cho đối số thứ hai bằng juxtap vị trí:

f[3]47

Điều tương tự tự nhiên hoạt động để lập chỉ mục mảng:

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

  z[1;2]
92

  z[1]2
92

5

In dòng mới

Nếu đầu ra của bạn phải có một dòng mới, bạn có thể muốn làm điều này:

`0:whatever,"\n"

Đừng . K2 (và có thể là các phiên bản khác) có tính năng gọn gàng nơi bạn có thể in danh sách các dòng:

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

Vì vậy, nếu bạn cần nối thêm một dòng mới vào đầu ra, chỉ cần làm:

`0:,whatever

3

Các dãy

Thông thường nếu bạn muốn tạo một vectơ các số liên tiếp bạn sử dụng !:

  !5
0 1 2 3 4

Nếu bạn muốn tạo một phạm vi bắt đầu bằng một số khác 0, thì bạn sẽ thêm một phần bù vào vectơ kết quả:

  10+!5
10 11 12 13 14

Có một vài cách tiếp cận khác thường có thể hoạt động tốt hơn cho một tình huống cụ thể. Ví dụ: nếu cơ sở và phần bù của bạn đã là thành viên của danh sách, bạn có thể sử dụng "nơi" hai lần:

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

Đối với các chuỗi tăng trưởng chậm hơn, hãy xem xét kết hợp "nơi" với "lấy":

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

Nếu bạn muốn tạo một phạm vi bội số, bạn có thể nhân kết quả của !hoặc bạn có thể quét ( \) danh sách các bản sao của kích thước bước:

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

Nếu bạn đang cố gắng tránh dấu ngoặc đơn, thì cái trước sẽ tốt hơn nếu độ dài của chuỗi thay đổi và kích thước bước được cố định, trong khi cái sau tốt hơn nếu kích thước bước là những gì có xu hướng thay đổi. Chọn đúng biến thể có thể lưu 1 hoặc 2 ký tự. Sự khác biệt giữa các bên cũng có thể có lợi cho bạn.


2

Các phôi từ dây là đắt tiền. Chỉ cần sử dụng eval. Điều này:

0.0$a

chỉ có thể trở thành thế này:

. a

Trong K5, nó ngắn hơn một byte:

.a

2

Mỗi quyền

Đôi khi, bạn có thể thấy mình viết (hoặc đến bằng cách đơn giản hóa) một biểu thức được ngoặc đơn được áp dụng qua từng đơn nguyên:

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

Nó ngắn hơn một ký tự để chuyển đổi mẫu này thành một ứng dụng của mỗi quyền:

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

1

Hoán vị theo chu kỳ

Dyadic !trong K3 / K4 là "xoay":

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

Khi "quét" ( \) được cung cấp với một động từ đơn âm, nó hoạt động như một toán tử điểm cố định. Trong K, các toán tử điểm cố định liên tục áp dụng động từ của chúng cho một giá trị cho đến khi giá trị ban đầu được xem xét lại hoặc giá trị dừng thay đổi. Kết hợp xoay với quét điểm cố định cung cấp một cách rất thuận tiện để tính toán một tập hợp các hoán vị tuần hoàn của danh sách:

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

Bạn có thể dùng cà ri !qua ngoặc hoặc ngoặc đơn để tạo động từ động từ (1!):

![1]\
(1!)\

(Lưu ý rằng 1!\có một hành vi hoàn toàn khác nhau!) Mỗi ​​trong số này có độ dài tương đương nhưng trước đây có thể được mong muốn hơn nếu sải chân xoay là một cái gì đó khác với 1; trong trường hợp này, dấu ngoặc phân định một biểu thức con được ngoặc đơn "miễn phí".

Ví dụ, đây là một chương trình ngắn kiểm tra thông qua lực lượng vũ phu xem một chuỗi x có chứa chuỗi con y (theo chu kỳ!):

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

Người dùng K5 hãy cẩn thận! K5 đã thay đổi ý nghĩa của dyadic !, vì vậy kỹ thuật này không quá dễ dàng. Nó sẽ hoạt động như mong đợi ở Kona.


1

Tránh điều kiện

K có cấu trúc có điều kiện ( :[) tương đương với kiểu Lisp cond:

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

Bạn có thể có bao nhiêu điều kiện tùy thích và nếu không có giá trị nào khớp với giá trị mặc định được trả về.

Đôi khi (như trong các chương trình hoặc chương trình đệ quy phụ thuộc vào một chuỗi các tác dụng phụ), không có cách nào sử dụng một trong những điều này. Tuy nhiên, trong các tình huống mà bạn có thể đủ khả năng để làm thêm một chút công việc, bạn thường có thể thay thế một "cond" bằng lập chỉ mục danh sách.

Hãy xem xét chương trình fizzbuzz khét tiếng . Được viết theo phong cách lập trình mệnh lệnh thông thường, chúng ta có thể đi với:

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

Có khá nhiều sự lặp lại ở đây trong các bài kiểm tra chia hết. Một cách tiếp cận khác nhau nhận ra rằng có 4 trường hợp (một số, chia hết cho 3, chia hết cho 5, chia hết cho 3 và 5) và cố gắng tính trực tiếp một chỉ số chọn một trong các trường hợp này từ danh sách:

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

Hai ký tự ngắn hơn, và sử dụng ngôn ngữ tốt hơn. Biết rằng danh sách chữ được đánh giá từ phải sang trái, chúng tôi cũng có được một số cơ hội chơi gôn bổ sung để kết hợp các biểu hiện phụ được sử dụng lại. Chúng tôi không thể dễ dàng thực hiện điều này trong phiên bản dựa trên cond, vì các trường hợp chuỗi không được đánh giá ở tất cả nếu chúng không được chọn:

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

Bây giờ chúng tôi đã lưu 5 ký tự tổng thể. Ngẫu nhiên, ví dụ cụ thể này hoạt động thậm chí còn đẹp hơn trong k5, vì chúng ta có quá tải "gói" /để xử lý bước nhân với một vectơ hệ số và tính tổng:

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

Cũng lưu ý rằng hành vi của "find" ( ?), tạo ra một chỉ mục ở cuối danh sách khóa nếu không tìm thấy mục, được thiết kế đặc biệt để hỗ trợ xử lý trường hợp "mặc định" trong loại lập chỉ mục này. Xem xét đoạn này để chuyển đổi nguyên âm thành chữ hoa:

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

Một trong những:

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

(Tôi biết tôi cũng muốn đọc hơn!)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.