默认写{(+/3<?⍵⍴6)×100÷⍵}1000

Write {(+/3<?⍵⍴6)×100÷⍵}1000 tacitly

受一些 Conor Hoekstra YouTube 视频的启发,我尝试在 APL 中做一些小步骤,并将我的小线条转换为无点样式。但是对于这个(1000 个 die-6 卷中 4、5 或 6 卷的百分比)我无法在重塑之前围绕如何消除欧米茄。

{(+/3<?⍵⍴6)×100÷⍵}1000

让我们一步步来:

{(+/3<?⍵⍴6)×100÷⍵}

首先我们需要将使用参数的函数的每一部分表达为of参数的函数。乘法结合了两个主要部分:

{+/3<?⍵⍴6}×{100÷⍵}

在最右边的部分,{100÷⍵},我们需要参数。有几种方法可以解决这个问题:

  1. 我们可以用一个identity function来表示:100÷⊢
  2. 我们可以 bind (a.k.a.curry) 左参数 100 到函数 ÷ 产生一个单子函数:100∘÷

让我们采用最后一种方法:

{+/3<?⍵⍴6}×100∘÷

在左边的部分,{+/3<?⍵⍴6},我们可以做同样的事情,但是需要注意两件事,每件事都可以用几种不同的方式处理:

  1. 我们有一个常量,6,作为我们函数最右边的部分。
    1. 我们可以把常量改成constant function6⍨
    2. 我们可以 commute(a.k.a。交换或切换) 的参数并使用恒等函数:6⍴⍨⊢
    3. 我们可以将正确的参数 6 绑定到函数 产生一个单子函数:⍴∘6
  2. 中间有一个单子函数?
    1. 我们可以组成?atop:?⍤⍴
    2. 我们可以组成?beside<:<∘?

让我们对每个问题采用最​​后一种方法:

(+/3<∘?⍴∘6)×100∘÷

这完全默认等同于单子函数 {(+/3<?⍵⍴6)×100÷⍵}。但是,我们还可以使用另一种技巧来消除括号。由于 × 是可交换的,我们可以交换它的参数以将更复杂的表达式放在右边:

100∘÷×(+/3<∘?⍴∘6)

但是,现在我们遇到了中间的 monadic +/ 问题。观察 < 在右边看到一个向量,在左边看到一个标量。在 F/s G v 对于标量函数 FG 以及标量 s 和矢量 v 的情况下, inner product s F.G v 是等价的,所以我们可以将求和与比较结合起来,如下所示:

100∘÷×3+.<∘?⍴∘6

或者,我们可以观察到求和等同于以 1 为底的求和,因为以 1 为底的位值为 (…,12, 11 , 10) = (..., 1, 1, 1) 所以如果我们有列表 (..., c, b, a) 并将其计算为以 1 为基数的数字,我们得到:

(… + c×12 + b×11 + a×10) =
(… + c×1 + b×1 + a×10 ) =
(… + c + b×1 + a×1) =
(... + c + b + a)

也就是我们列表的总和。我们可以这样写:

100∘÷×1⊥3<∘?⍴∘6