Поради для гри в гольф в Хуску


15

Хуск - це зовсім нова мова для гольфу, створена користувачами PPCG Лео та Згарбом . Він почав бути все більш конкурентоспроможним, часто тримаючись поруч або навіть б’ючи мов, як відомо, дуже стислих, таких як Jelly і 05AB1E.

Перелічимо декілька методів гольфу, які дещо характерні для лушпиння. Як завжди, будь ласка, опублікуйте одну пораду за кожну відповідь.



1
@totallyhuman перша відповідь Хука все ще не така вже нова
H.PWiz

Відповіді:


10

Використовуйте повернене значення з предикатів

У Husk функції, які перевіряють свої вхідні дані на деяку властивість, зазвичай повертають значущий результат у truthy випадках, оскільки будь-яке додатне ціле число є truthy.

Приклади:

≠  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

Використовуйте переповнені мітки рядків

Як ви вже можете знати, [₀-₉]+|[₀-₉]це регулярний вираз для синтаксису, щоб викликати інший рядок, ніж той, в якому ви зараз перебуваєте.

Ця порада особливо корисна, якщо ви хочете, щоб функція, визначена в певному рядку, називалася аргументом більш ніж однієї з функцій у таблиці нижче, або як аргумент однієї або декількох функцій нижче та сама по собі.

Таблиця функцій:

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

Рядки у вашому коді позначені відповідними індексами на основі 0, зверху вниз. Якщо M <N , де M є етикетка та N це кількість рядків в коді, мітка просто являє собою функцію , визначену в рядку М . Якщо N ≤ M <N * 6 , він представляє функцію з таблиці вище за індексом ⌊M ÷ N⌋ з функцією, визначеною у рядку M mod N як її першим аргументом. Якщо N * 6 ≤ M , підвищується індексна помилка.


5

Лямбди можуть бути коротшими, ніж нові функції

Як ви, напевно, знаєте, якщо у вас є багаторядкова програма, ви можете посилатися на рядки з підписками ₀…₉, наприклад у випадку

f
g

буде посилатися на функцію g. Тепер, якщо ви завжди застосовуєте входи до функції g(і використовуєте її кілька разів); щось на зразок цього:

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

Вам слід ввести лямбда, оскільки це заощадить вам 1 байт для кожного додаткового використання:

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

Зворотним може бути і правда

У випадку з самореференційними лямбдами ( φχψ), є особливий випадок, коли ви застосовуєте входи безпосередньо до рекурсивної функції, у цих випадках вам краще скористатися індексом замість визначення нової лямбда та використанням .


5

Використання Γ

Основне використання вбудованого Γ, відомого як узгодження шаблонів у списках або розробка списку , - розділити список на голову та хвіст та застосувати до них бінарну функцію. Це відповідає схемі 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

Комбінатори можна застосовувати до функцій вищого порядку

Припустимо, у вас є список цілих чисел X , і ви хочете порахувати загальну кількість елементів X , більших за довжину (X) . Counting елементи , які задовольняють предикат робляться з функціями вищого порядку #, але тут предикат (будучи більше довжинами (X) ) залежить від X . Рішення полягає в тому, щоб застосувати комбінатор до #і функцію , o>Lяка перевіряє , є чи список коротше , ніж число. У функції передається Ṡ#o>Lсписок X , передається o>Lчастково застосована функція #, а X надається #як другий аргумент.

Загалом, якщо αфункція вищого порядку, βто бінарна функція та γодинарна функція Ṡαβеквівалентна псевдокоду Haskell

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

§αβγ еквівалентно

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

і ~αβγеквівалентно

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

допоки типи відповідають.

В якості іншого конкретного прикладу §►δṁ≠Pзнаходимо перестановку списку X, яка максимізує суму абсолютних різниць до відповідних значень X ( δṁ≠зіпсує два списки, використовуючи абсолютну різницю і приймає суму).


3

Значення за замовчуванням

Хеск не такий суворий, як Haskell, коли ви стикаєтеся з проблемою, коли, наприклад, намагаєтесь отримати lastелемент порожнього списку. Для цього використовується попередньо визначені значення, ось список значень за замовчуванням, максимумів і мінімумів:

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

* Тут ∞ повинен представляти нескінченний список відповідного максимуму (див. Приклад нижче)

Примітка. Для кортежів (X, Y) вони використовуватимуть значення для кожного компонента окремо.


Коли вони використовуються

Хоча максимуми і мінімуми використовуються лише для ▲▼порожніх списків (наприклад husk -u "▼" "[]:LLN", повертає нескінченний список Inf), значення за замовчуванням використовуються в кількох місцях:

  • складання порожніх списків, не надаючи собі значення ( Fі )
  • попереднє значення за замовчуванням (з Θ)
  • коли читання ( r) не вдається
  • отримання першого / останнього елемента ( ←→) або індексації в один ( !)
  • узгодження шаблону ( Γ) у порожніх списках
  • за допомогою або в порожніх списках
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.