赫斯基打高尔夫球的秘诀


15

Husk是由PPCG用户LeoZgarb创建的一种非常新的高尔夫语言。它已经开始变得越来越有竞争力,经常保持紧密甚至击败那些非常简洁的语言,例如Jelly和05AB1E。

让我们列出一些特定于Husk的高尔夫技术。与往常一样,请为每个答案发布一个提示。



1
@totallyhuman 第一个Husk答案仍然不是那么新
H.PWiz

Answers:


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

使用溢出线标签

您可能已经知道, [₀-₉]+|[₀-₉]正则表达式的语法可以调用与当前所在行不同的行。

如果希望将在特定行上定义的函数作为下表中多个函数的自变量调用,或者将其作为下面一个或多个函数的自变量,则本技巧特别有用。

功能表:

+----------+----------+
|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÷N⌋的函数,并将在行M mod N处定义的函数作为其第一个参数。如果N * 6≤M,则会产生索引错误。


5

Lambda可以比新功能短

如您可能知道您有多行程序,则可以使用带下标的行₀…₉,例如

f
g

将参考该功能g。现在,如果您始终将输入应用于函数g(并多次使用);像这样的东西:

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

您应该引入一个lambda,因为它可以为您每次额外使用节省1个字节:

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

反之亦然

对于自引用lambdas(φχψ),在特殊情况下,您将输入直接应用于递归函数,在这些情况下,最好使用下标而不是定义新的lambda并使用


5

用途 Γ

内置的主要用途(Γ称为列表上的模式匹配列表解构)是将列表分为头和尾,并对它们应用二进制函数。这对应于Haskell模式匹配惯用法

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

其中<something>是含有表达xxs并且可能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

listNFlistF什么listNlist:输入a被省略,返回类型的默认值来代替。在极少数情况下,它可能比右折短,例如在此答案中

作为的递归版本的一个示例Γ,该函数Γλ·:o⁰↔按第一,最后,第二,倒数第二,第三,倒数第三的顺序对列表进行随机排序。 在线尝试! 该函数f是显式lambda λ·:o⁰↔,其参数是整个函数。要做的f是用反转尾巴,然后用递归调用main函数o⁰,最后用固定头·:。当然,Γ·:o₀↔它要短一个字节,但是如果该行包含的内容不是此函数,则该行不起作用。


3

组合器可以应用于高阶函数

假设您有一个整数X的列表,并且想要计算X中大于length(X)的元素总数。满足谓词计数元件与更高阶函数来完成#,但这里的谓词(即大于长度(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

外壳的默认值

Husk不像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)失败时
  • 获取第一个/最后一个元素(←→)或索引一个(!
  • 模式匹配 (Γ空列表上的)
  • 使用在空列表上
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.