APL高尔夫技巧


28

我最近发起了一场代码高尔夫挑战赛,看来胜利者是GolfScript(惊喜,惊喜!)。有趣的是,还有另一个非常强大的竞争对手,有机会赢得GolfScript。它的名字叫APL。我在这里看到了许多用APL编写的答案。看来这种语言对于代码打高尔夫球相当有效,因此我决定询问您对APL程序了解的任何代码打高尔夫球技巧。随时发布一些代码示例。看到实际的语言通常非常有趣。

Answers:


23

编辑:对于人读这谁不知道APL的所有,但想利用它,掌握Dyalog APL是一种非常好的资源。

  1. 评估严格按照从右到左的顺序进行。这包括设置变量,因此请充分利用它。

    2+a, 1+a←1 -> 3 4

    a设置为11+a评估为2a,2评估为1 22+1 2评估为3 4

  2. 像C一样,可以与一个函数(即)组合a +← 3。与C不同,这是通用的:foo F← bar设置fooF bar。有点不直观,作为返回的表达式bar,不是F bar

    它也可以使用匿名函数:

          a←0
          a+←3 ⋄ a
    3
          a+←3 ⋄ a
    6
          a { ⍵/'!' } ←4 ⋄ a
    !!!!
    
  3. 您可以A[3]←8像期望的那样分配给数组:。但是,您也可以同时分配多个项目:A[3 5 6]←9 1 4或什至A[3 5 6]←9,将它们全部设置为同一项目。当然,您也可以在此处添加功能。然后,该函数将分别应用于每个元素,就像您所做的那样

  4. 是你的朋友,即使他对此不太满意。

    1. 如果F为dyadic,则dyadic 切换参数:a F b<-> b F⍨ a。打高尔夫球时这很方便,因为它可以避免使用牙套:

      (F G H x) K y      <->     y K⍨ F G H x
      

      确实会改变评估顺序,因为总是先评估右手,然后评估左手。

    2. 如果F为dyadic,则monadic 将相同的参数应用于函数的两侧:

            5⍴5
      5 5 5 5 5
            ⍴⍨5
      5 5 5 5 5
      

      该参数仅计算一次。这尤其适用于外部乘积,即,可以将数组中的每个值与同一数组中的其他值进行比较,∘.=⍨而不必这样做x∘.=x←(whatever)

    3. 如果F为monadic,则不执行任何操作,但会将函数与参数分开。因此,如果函数很复杂,它仍然可以节省花括号:

            {⍵+3}⍣5 6
            ∇{⍵+3}              
           ∇ ⍣ 5 6              
            ({⍵+3}⍣5)6
      21
            {⍵+3}⍣5⍨6
      21
      
  5. 学习习语!然后打高尔夫球。例如:

    ((((1↑⍴X),⍴Y)↑X)^.=Y)⌿X
    

    可以机械地转换为:

    X⌿⍨Y^.=⍨X↑⍨(1↑⍴X),⍴Y
    

    然后进一步进入:

    X⌿⍨Y^.=⍨X↑⍨(⊃⍴X),⍴Y
    

    (第1↑一个)在这种情况下等于(取一个)。并且可能:

    X⌿⍨Y^.=⍨X↑⍨(≢X),⍴Y
    

    (tally)⊃⍴除标量外,所有值均等于(形状的第一个元素)。


除了拥有树莓派版本外,还有没有办法获得免费许可证?
Fabinout 2014年

显然,这是一种合法的获取方式。
Fabinout 2014年

2
@Fabinout:在dyalog.com上,您可以下载免费的Windows版本。单击“下载区域”,然后单击“未注册的下载”。它将使您无法注册,但否则它将完全起作用并且免费合法。如果您是学生,则可以通过填写表格免费获得普通版。如果您不住在一个因盗版而毁了您的生活的国家,那么您就会知道该怎么做。
marinus 2014年

还有Nars2000,这是一个开源实现,具有比Dyalog更多的功能(和一些错误)。它的某些功能在打高尔夫球时很方便,例如质数功能或多组功能。
Tobia 2014年

1
有GNU APL。
M. Alaggan

14

火车

A(f g h)B      ←→  (A f B)g A h B  ⍝ fork
 (f g h)B      ←→  (  f B)g   h B  ⍝ fork
A(  g h)B      ←→         g A h B  ⍝ atop
 (  g h)B      ←→         g   h B  ⍝ atop
 (A g h)       ←→  ({A} g h)       ⍝ "Agh" fork
 (f g h k)     ←→  (f (g h k))     ⍝ 4-train
 (f g h k l)   ←→  (f g (h k l))   ⍝ 5-train, etc
 (f g h k l m) ←→  (f(g h(k l m))) ⍝ groups of 3 from the right, last could be 2
  f∘g B        ←→    f g B         ⍝ "compose" operator, useful in trains
A f∘g B        ←→  A f g B

这是否意味着为了将来的读者,我们不应该告诉Oberon如何缩短它?
亚当

不,像平常在PPCG上一样。在表达式达到最短(我认为是最短)之后,我将删除该行。这很容易-我认为您个人不会从中受益。
ngn

我可以将其降低到16,但是我没有使用您的任何提示,所以也许我走了。
亚当

@亚当好,您正在使用的列车:)我的是相似的,但较长时间,因为我没想到⎕ML的
NGN

是不是“从右边开始的3组”?
亚当

7

火车上/火车上的技巧

使用火车,你可能要使用的减少f/同样数目的钱+/,甚至重复减少//。但是,如果火车在减法项的左边有更多部分,则需要括号以创建一个顶。这里有一些保存字节的技巧。

使用1∊代替单子∨/∨⌿布尔数组

任务:给定两个相等长度的字符串A和B,如果A和B的任何对应字符相等,则返回2,否则返回0。例如,A←'abc'B←'def'赋予0A←'abc'B←'dec'给人2

dfn解决方案可能是,A{2×∨/⍺=⍵}B但您想通过默认来缩短它。A(2×∨/=)B是不会工作,因为列车编组规则解析这个作为2 (× ∨/ =),但你想2 × (∨/=)

观察∨/∨⌿在布尔向量上(∨/,∨⌿,对于较高秩的数组)询问是否存在1,即1∊,因此我们可以将火车写为2×1∊=

请注意,它使用了正确的参数,因此不能使用它来分别减少每一行或每一列。

使用1⊥代替单子+/+⌿

任务:给定一个列表L和一个索引N,返回第N个列表的和的三倍。例如L←(3 1 4)(2 7)N←1给出24

dfn解决方案可能是,N{3×+/⍺⊃⍵}L但您想通过默认来缩短它。N(3×+/⊃)L是不会工作,因为列车编组规则解析这个作为3(× +/ ⊃),但你想3 × (+/⊃)

观察到,评估一元数(以1为底)的数字列表等同于对该列表求和,因为∑ { abcd } =  a + b + c + d  =(a ×1³)+(b ×1² )+(c ×1¹)+(d ×1⁰)。因此+/a b c d与相同1⊥a b c d,我们可以将火车写成3×1⊥⊃

请注意,在高级参数上,1⊥等效于+⌿

使用f.g的,而不是f/g标量和/或向量参数

任务:给定一个列表L和一个数字N,当L的元素除以NEg L←31 41 59N←7给出时,通过最小除法余数返回范围1 1 2 3

dfn解决方案可能是,N{⍳⌊/⍺|⍵}L但您想通过默认来缩短它。N(⍳⌊/|)L是不会工作,因为列车编组规则解析这个作为⍳ (⌊/) |,但你想⍳ (⌊/|)

A f.g B当参数是标量和/或向量时,标量两个函数的内积与f/ A g B它们都相同,因为它们都是(A[1] g B[1]) f (A[2] g B[2]) f (A[3] g B[3])等,所以我们可以将训练写为⍳⌊.|

请注意,这不适用于更高级别的阵列。

使用∊⊆的,而不是/用布尔左,简单的矢量右参数

任务:给定列表L和数字N,请过滤列表,以便仅保留大于N的数字。例如L←3 1 4N←1给出3 4

dfn解决方案可能是,N{(⍺<⍵)/⍵}L但您想通过默认来缩短它。N(</⊢)L不会起作用,因为绑定规则会将其解析为,(</) ⊢但是您要/作为函数复制而不是运算符reduce

具有布尔型左引数的二元对数根据左引数中1的游程对右引数进行分区,删除由0表示的元素。这几乎是我们想要的,除了不必要的分区。但是,我们可以通过应用monadic摆脱分区。这样{(⍺<⍵)/⍵}就可以成为{∊(⍺<⍵)⊆⍵},因此我们可以将我们的火车写为∊<⊆⊢

请注意,这不适用于更高级别的阵列。

使用0⊥代替数字参数⊢/⊢⌿与数字参数一起使用

任务:给定一个列表L和多个N,乘法的N个与腿的最右边的元件L←3 1 4N←2给出8

dfn解决方案可能是,N{⍺×⊢/⍵}L但您想通过默认来缩短它。N(⊣×⊢/⊢)L是不会工作,因为列车编组规则解析这个作为⊣ (× ⊢/ ⊢),但你想⊣ × (⊢/⊢)

观察到0⊥数值数组上的相同⊢⌿,因此我们可以将火车写为⊣×0⊥⊢

请注意,这将选择较高级别数组的最后一个主要单元。


1
也许您可以将此聊天答案添加到此答案中?
J.Sallé18年

1
@J.Sallé添加了。
亚当

7

乘法与加法结合

(a×b)+C  ->  a⊥b,C
(C)+a×b  ->  a⊥b,C
(a×b)-C  ->  a⊥b,-C

假设:

  • a并且b用作左引数时不需要进一步括号的术语

  • C 是用作左参数时可能需要括号的表达式

  • a b C 计算为数字标量


5

复数

通常会被忽略,它们提供了绝佳的机会来缩短处理网格,迷宫,分形或几何图形的表达式。

0j1⊥¨    0j1⊥   ⍝ pair(s) of reals -> complex
11 9∘○¨  11 9○  ⍝ complex -> pair(s) of reals
|z0-z1          ⍝ distance between two points
0j1×z   0j¯1×z  ⍝ rotate by ±90° around (0,0)
0j1*⍳4          ⍝ the four cardinal directions
+z       -+z    ⍝ reflect across x or y axis
+\0,z           ⍝ sequence of steps -> path
2-/z            ⍝ path -> sequence of steps
0j1⊥¨n-⍳2⍴1+2×n ⍝ lattice centred on (0,0)

4

标引模向量长度

⊃i⌽a通常比朴素⊃a[(≢a)|i]a⊃⍨i|⍨≢a(在这里a是向量,i是整数,并且⎕io为0)短

关于此的一个有用的变化(感谢EriktheOutgolfer指出):I↑Y⌽⍨I×X其中哪里Y是一些长度I向量的串联,并且X是我们要选择的长度向量的索引,例如:3↑'JanFeb...Dec'⌽⍨3×month


3

常数函数

=⍨≠⍨感谢ngn。

有时,您只需要为列表中的每个元素分配一个值。尽管您可能会想使用{value}¨,但使用起来却比较短,value⊣¨ 但对于某些常用值,您可以使用来更短⎕IO←0

¯1⍬⍸list

0⍬⍳list

1⍬⍷list

请注意,这些仅适用于列表(尽管它们可能是嵌套的)。对于更高级别的数组,可以使用以下命令获取全0和全1:

1=⍨

0≠⍨

如果设置⎕ML←0,则可以使用以下方法将所有数字都设为零(就像):

如果仅需要一个数字,则可以使用monadic 来获取1或0,而不是使用1⊣0⊣


有时,列表的每个元素只需要一个值。 ”-可能值得注意:当该值是列表的第一个元素时,您可以使用⊣\
ngn

@ngn我想说,/功绩自己的岗位。
亚当

2

使用

避免括号

(通勤)可以通过避免括号来节省字节。只要您有一个函数需要在左参数上加上括号,而右参数不需要上括号,则可以保存一个字节,例如(A<B)÷CC÷⍨A<B

双数组

要将数组的副本附加到其末尾,请使用,⍨A⍪⍨A

双数

2∘×您可以使用而不是使用double,+⍨因为它将参数添加到自身:1+2∘×1++⍨

平方数

2*⍨Y您可以使用而不是平方,×⍨Y因为它会将参数与自身相乘:2*⍨A+B×⍨A+B

随机排列

?⍨N将为您提供长度的随机排列N

自分类

找到每个主要像元第一次出现的索引 ⍳⍨A

计算布尔向量中的尾随1

不必+/∧\⌽B计算N可以使用多少个尾随的1 ⊥⍨

反向组成

A f∘g BA f g B,但如果需要(g A) f B,请使用f⍨∘g⍨

反向减少

f/ a1 a2 a3a1 f (a2 f a3)。如果需要(a1 f a2) f a3,请使用f⍨/⌽

反向扫描

f\ A B C
A (A f B) (A f (B f C))

f⍨/∘⌽¨,\ A B C
A (A f B) ((A f B) f C)

f⍨\⌽ A B C
((A f B) f C) (B f C) C

⌽f/∘⌽¨,\⌽ A B C。是
(A f (B f C)) (B f C) C


2

枚举字符串中的字符,不带 ⍳≢

任务:给定两个字符串S和T,列出其串联索引。例如S←'abcd'T←'xyz'给出1 2 3 4 5 6 7

dfn解决方案可能是,S{⍳≢⍺,⍵}T但您想通过默认来缩短它。⍳≢,是不会工作,因为火车解析规则解析此作为(⍳)≢(,),但你想(⍳≢),

左参数为空的Dyadic 根据其当前顺序对简单字符数组进行评分,该顺序与相同⍳≢。这样{⍳≢⍺,⍵} 就可以成为{⍬⍋⍺,⍵},因此我们可以将火车写成⍬⍋,

请注意,这不适用于数字数组或混合数组。


哇,不知道那是一回事。
扎卡里
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.