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


15

Husk là một ngôn ngữ chơi golf khá mới, được tạo bởi người dùng PPCG LeoZgarb . Nó đã bắt đầu ngày càng cạnh tranh hơn, thường ở gần hoặc thậm chí đánh bại các ngôn ngữ được biết đến là rất ngắn gọn, chẳng hạn như Jelly và 05AB1E.

Chúng ta hãy liệt kê một số kỹ thuật chơi gôn có phần đặc trưng với Husk. Như mọi khi, xin vui lòng gửi một lời khuyên cho mỗi câu trả lời.



1
@totallyhuman Câu trả lời đầu tiên của Husk Vẫn chưa có gì mới
H.PWiz

Câu trả lời:


10

Sử dụng giá trị trả về từ các vị từ

Trong Husk, các hàm kiểm tra đầu vào của chúng cho một số thuộc tính thường sẽ trả về kết quả có ý nghĩa trong các trường hợp trung thực, vì bất kỳ số nguyên dương nào là trung thực.

Ví dụ:

≠  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

Difference sự khác biệt thích hợp có nghĩa là sự khác biệt của các điểm mã cho ký tự. Nó cũng đề cập đến thứ tự lập luận. tức là cho <x y, sẽ làx-y


7

Sử dụng nhãn tràn dòng

Như bạn có thể đã biết, [₀-₉]+|[₀-₉]là regex cho cú pháp gọi một dòng khác với dòng bạn đang sử dụng.

Mẹo này đặc biệt hữu ích nếu bạn muốn một hàm được xác định trên một dòng cụ thể được gọi là đối số của nhiều hơn một trong các hàm bên dưới hoặc làm đối số cho một hoặc nhiều hàm bên dưới và chính nó.

Bảng chức năng:

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

Các dòng trong mã của bạn được gắn nhãn với các chỉ số dựa trên 0 tương ứng của chúng, từ trên xuống dưới. Nếu M <N , nơi M là nhãn và N là số dòng trong mã của bạn, nhãn chỉ đại diện cho chức năng quy định tại dòng M . Nếu N ≤ M <N * 6 , nó đại diện cho hàm từ bảng trên tại chỉ mục ⌊M N⌋ với hàm được xác định tại dòng M mod N là đối số đầu tiên. Nếu N * 6 M , một lỗi chỉ số được đưa ra.


5

Lambdas có thể ngắn hơn chức năng mới

Như bạn có thể biết nếu bạn có một chương trình nhiều dòng, bạn có thể tham khảo các dòng có các mục con ₀…₉, ví dụ như trong trường hợp

f
g

sẽ đề cập đến chức năng g. Bây giờ nếu bạn luôn áp dụng các đầu vào cho hàm g(và sử dụng nó nhiều lần); đại loại như thế này:

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

Bạn nên giới thiệu lambda vì nó giúp bạn tiết kiệm 1 byte cho mỗi lần sử dụng bổ sung:

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

Điều ngược lại cũng có thể đúng

Trong trường hợp lambdas tự tham chiếu ( φχψ), có trường hợp đặc biệt khi bạn áp dụng các đầu vào trực tiếp cho hàm đệ quy, trong những trường hợp này, bạn nên sử dụng chỉ mục thay vì xác định lambda mới và sử dụng .


5

Sử dụng Γ

Việc sử dụng chính của tích hợp Γ, được gọi là khớp mẫu trong danh sách hoặc giải cấu trúc danh sách , là chia danh sách thành phần đầu và đuôi và áp dụng hàm nhị phân trên chúng. Điều này tương ứng với thành ngữ Haskell phù hợp với thành ngữ

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

trong đó <something>một biểu thức có chứa x, xsvà có thể f. Có 4 quá tải Γ, mỗi cái hoạt động khác nhau một chút.

list

Quá tải đầu tiên list, có một giá trị avà hàm nhị phân f. Nó trả về một chức năng mới có một danh sách, trả về anếu nó trống và gọi fvào đầu và đuôi nếu nó không trống. Ví dụ: Γ_1€lấy một danh sách, trả về -1nếu nó trống và chỉ mục xuất hiện đầu tiên của phần tử đầu tiên ở đuôi nếu không.

listN

Quá tải thứ hai, listNtương tự như list, ngoại trừ ađược bỏ qua và giá trị mặc định của loại trả về được sử dụng thay thế. Ví dụ, Γ€tương đương với Γ0€, vì giá trị số mặc định là 0.

Trong thực tế, listNđược sử dụng thường xuyên hơn list, vì giá trị mặc định là không liên quan hoặc chính xác những gì bạn cần. Một mô hình phổ biến là Γ~αβγ, nơi αβγcó ba chức năng; điều này áp dụng βcho phần tử đầu tiên và γphần đuôi, và kết hợp các kết quả với α. Nó đã được sử dụng ví dụ trong câu trả lời này . Các mẫu khác bao gồm chỉ Γo:αáp dụng αcho phần tử đầu tiên và Γ·:mαđể áp dụng αcho tất cả các phần tử ngoại trừ phần tử đầu tiên. Thứ hai đã được sử dụng trong câu trả lời này .

listF

Quá tải thứ ba là một chút liên quan. Giống như list, nó nhận một giá trị avà một hàm fvà trả về một hàm mới gcó một danh sách. Tuy nhiên, lần này fcó một đối số hàm bổ sung, gchính nó và có thể gọi nó trên bất kỳ giá trị nào (bao gồm, nhưng không giới hạn ở phần đuôi của danh sách đầu vào). Điều này có nghĩa là listFthực hiện một sơ đồ đệ quy chung trong danh sách. listFkhông được sử dụng rất thường xuyên, vì đệ quy rõ ràng với list/ listNthường có cùng độ dài hoặc ngắn hơn, như trong câu trả lời này .

listNF

listNFlistFnhững gì listNlist: đầu vào ađược bỏ qua, và giá trị mặc định của kiểu trả về được sử dụng để thay thế. Trong trường hợp hiếm hoi, nó có thể ngắn hơn một nếp gấp bên phải, ví dụ trong câu trả lời này .

Như một ví dụ về các phiên bản đệ quy của Γ, hàm này Γλ·:o⁰↔xáo trộn một danh sách theo thứ tự đầu tiên, cuối cùng, thứ hai, thứ hai đến cuối cùng, thứ ba, thứ ba đến cuối cùng, v.v. Hãy thử trực tuyến! Hàm fnày là lambda rõ ràng λ·:o⁰↔, có đối số là toàn bộ hàm. Điều gì flàm là đảo ngược đuôi với , sau đó gọi hàm chính theo cách đệ quy với o⁰, và cuối cùng giải quyết đầu trở lại với ·:. Tất nhiên, Γ·:o₀↔là một byte ngắn hơn, nhưng không hoạt động nếu dòng chứa thứ gì khác ngoài chức năng này.


3

Bộ kết hợp có thể được áp dụng cho các chức năng bậc cao hơn

Giả sử bạn có một danh sách các số nguyên X và bạn muốn đếm tổng số phần tử của X lớn hơn chiều dài (X) . Yếu tố đếm đáp ứng một vị được thực hiện với các chức năng bậc cao #, nhưng ở đây vị (là lớn hơn chiều dài (X) ) phụ thuộc vào X . Giải pháp là để áp dụng các combinator tới #và chức năng o>Lmà kiểm tra xem một danh sách ngắn hơn một số. Trong hàm Ṡ#o>L, danh sách X được truyền tới o>L, hàm được áp dụng một phần được chuyển đến #X được đưa vào #làm đối số thứ hai.

Nói chung, nếu αlà hàm bậc cao hơn, hàm βnhị phân và γhàm unary, Ṡαβthì tương đương với mã giả Haskell

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

§αβγ tương đương với

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

~αβγtương đương với

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

miễn là các loại phù hợp.

Như một ví dụ cụ thể khác, §►δṁ≠Ptìm thấy một hoán vị của danh sách X tối đa hóa tổng số chênh lệch tuyệt đối với các giá trị tương ứng của X ( δṁ≠nén hai danh sách sử dụng chênh lệch tuyệt đối và lấy tổng).


3

Giá trị mặc định của Husk

Husk không nghiêm khắc như Haskell khi bạn gặp rắc rối khi ví dụ bạn cố gắng lấy lastyếu tố của một danh sách trống. Để đạt được điều này, nó sử dụng các giá trị được xác định trước, đây là danh sách các giá trị mặc định, cực đại và cực tiểu:

.------------------------------------.---------------.----------.-------.
|   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  |
'------------------------------------'---------------'----------'-------'

* Ở đây nên biểu thị một danh sách vô hạn của mức tối đa tương ứng (xem ví dụ bên dưới)

Lưu ý: Đối với các bộ dữ liệu (X, Y), nó sẽ sử dụng các giá trị cho từng thành phần riêng biệt.


Khi chúng được sử dụng

Mặc dù cực đại và cực tiểu chỉ được sử dụng cho ▲▼các danh sách trống (ví dụ: husk -u "▼" "[]:LLN"sẽ trả về một danh sách vô hạn Inf), các giá trị mặc định được sử dụng ở một vài vị trí:

  • gấp các danh sách trống mà không tự cung cấp một giá trị ( F)
  • chuẩn bị giá trị mặc định (với Θ)
  • khi đọc ( r) thất bại
  • lấy phần tử đầu tiên / cuối cùng ( ←→) hoặc lập chỉ mục thành một ( !)
  • khớp mẫu ( Γ) trên danh sách trống
  • sử dụng hoặc vào danh sách trống
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.