3
(2&*~) 15 7 3 1 

以上是成语。最后是痕迹和最终结果。我知道这个短语是一个单子,我知道因为 ~ 它有一个左右参数。如果您运行“15 7 3 1(2&*) 15 7 3 1”,则会发生相同的输出。我还知道正确的表格是 2 的 1、3、7、15 的幂,其他条目是它们的基数乘以 2 的幂,但我就是不明白为什么。

在相关的说明中,这是来自 Rosetta Code 网站上的 ethopian 乘法的短语(实际上,这也是,我在试图弄清楚这一点时已经走了这么远)和 '(1>.<.@-:)^: a:' 是短语。

(1>.<.@-:)^:a: 27
27 13 6 3 1

但是 (1>.<.@-:)^: 27 返回一个盒子的版本,我希望它运行 27 次。

在三个相关问题中的最后一个(这些都与分解 Ethopian 乘法代码有关),完整代码如下:

double =:  2&*
halve  =:  %&2           NB.  or the primitive  -:
odd    =:  2&|

ethiop =:  +/@(odd@] # (double~ <@#)) (1>.<.@halve)^:a:

并且可以简单地替换为:

ethiop =:  +/@(2&|@] # (2&*~ <@#)) (1>.<.@-:)^:a:

这很好用!成功地冲了上去,当我想到有一个在命令行上工作的一元替身时,我完全从悬崖上掉下来了:

+: 98
196

而且双精度运算符必须比带有附加常量的双精度运算符快,也许双精度运算符只是移位,所以我认为

ethiop =:  +/@(2&|@] # (+:~ <@#)) (1>.<.@-:)^:a:

会工作......但它没有。

我尝试过大写字母、连词等,但没有任何效果,它总是说“域错误”。我开始认为代码依赖于二元调用的 monad 以一种我不明白的方式创建加倍表。

唯一的好处是 J 动词奇数与测试奇数无关。

任何人都可以向我解释这些事情,也许用英语解释程序是如何工作的?不是算法如何工作,而是如何实现算法。我记得当我在 1970 年玩 IBM 1130 APL 时。这是一个以 8k 字运行的 APL 解释器,不用说,它是有限的。例如,它有一个滚动但没有交易。解释器逐步进出内存,1130 支持代码覆盖,它将您的子例程分成组,当一个组调用另一个组时,它将从磁盘加载新组(是的,8k 中的伪交换)。因此,我使用各种方案编写了 deal 的版本,并且随机地,我们会找到一个可以逐步进入和退出而无需搜索的版本,而那个版本,无论写得多么糟糕,有多少行和多少解释器操作都会运行 10 次和其他任何东西一样快。我不知道自己在做什么,我会不断地添加 ravels 和无意义的作业,并跨行打破陈述或将它们组合起来,直到我得到一个无需查找即可运行的语句。(正在寻求的 52 交易 52 可能需要 45 秒)。

然后昨晚我计算了 J 中的第 150,000 个斐波那契数。它必须是 64 位版本,并且花了 1 小时 17 分钟。我用了精确的算术,这个数字有 31349 位,它从 1012838344936638038 开始......我意识到 1130 永远不可能计算出这个,这个数字不合适,因为你需要三个,而最大的一个有 32k 16 位字。我想学习可以做到这一点的语言,但是文档中缺少一些我没有得到的东西。

 trace '(2&*) 15 7 3 1' 
 --------------- 4 Conj -------
 2
 &
 *
 2&*
 --------------- 3 Adverb -----
 2&*
 ~
 2&*~
 --------------- 8 Paren ------
 (
 2&*~
 )
 2&*~
 --------------- 0 Monad ------
 2&*~
 15 7 3 1
 491520 229376 98304 32768
   1920    896   384   128
    120     56    24     8
     30     14     6     2
 ==============================
 491520 229376 98304 32768
   1920    896   384   128
    120     56    24     8
     30     14     6     2

斐波那契脚注:

]t150k=:6!:2 'a150k =: $ ":r150k=: {:  (,+/@(_2&{.) )^:150000 (0x 1x)'
4631.62

0 60 60 #: t150k
1 17 11.6167
r150k
10128383449366380384728502706681008427227914006240871521944866167854579423510169
50198752571599303492471943589300904953648270811064370506598260395645679940891823
17307901573781852234222080308236027906733606532470814177610613237408102006595571
1949713927351702...
a150k
31349
4

2 回答 2

5

答案记录在Bond (&)下,其中记录了以下身份以供二元使用:

x m&v y ↔ m&v^:xy

在您的示例中,m 是2,v 是*,并且 x 和 y 都是四个数字的列表15 7 3 1

等式右边的短语包括^:x("to the power x"),这与取动词并将其应用 x 次相同。动词是2&*这样,它被应用了十五次。还有七次。而且也是三遍。而且还有一次。这四个应用程序的结果构成了输出的四行。

关注第三个并使用括号强调,这就是正在发生的事情。

   (2&* (2&* (2&* (15 7 3 1))))
  120 56 24 8

这与

   (2&*)^:3 (15 7 3 1)
120 56 24 8

这与

   (3) 2&* (15 7 3 1)
120 56 24 8

让我们通过 3 应用所有非负整数来查看模式:

   (0 1 2 3) 2&* (15 7 3 1)
 15  7  3 1
 30 14  6 2
 60 28 12 4
120 56 24 8

此时,与原始表格的相似性可能会使该表格的含义易于理解:

   (15 7 3 1) 2&* (15 7 3 1)
491520 229376 98304 32768
  1920    896   384   128
   120     56    24     8
    30     14     6     2

同样的事情正在发生,只是因为你给出了一些更高的数字而更频繁地发生。

于 2011-10-17T03:22:09.707 回答
2

这只是您的问题的初步尝试,因为到目前为止没有人回答:

副词的作用域很长:

(2&*~) <-> ((2&*)~)

由 bond 返回的函数的二元情况是powered

(x m&v y) <-> ((m&v)^:x y)

2&*每次应用时都会将其参数加倍,因此 power2&*将其参数乘以 的幂2

(1>.<.@-:)^: 27定义一个动词(因为^:是连词),但不运行它。在原始短语foo^:a:中是动词和27论点。什么时候a:它的正确论点^:只是运行直到它收敛。

Monadic+:加倍了它的论点,但是2&*and的二元格+:没有任何关系,也不能互换。请注意,这double~是一个钩子的左侧,它总是被称为 dyadically。

唯一的好处是 J 动词奇数与测试奇数无关。

实际上,如果2&| y是奇整数,如果是偶整数,那么它是对奇数的测试。1y0

现在,为了尝试用简单的英语解释该算法在做什么,让我们逐个短语地看它,并使用12 ethiop 27以下示例:

+/@(2&|@] # (2&*~ <@#)) (1>.<.@-:)^:a:

是一个钩子。在钩子中,右侧始终是单子,左侧始终是二元组。

(1 >. (<. @ -:)) ^: a:

Monad (<. @ -:)= floor @ half将其参数减半并向下舍入,然后1 >. (<. @ -:返回该和的最小值1^:a:一直持续到收敛并列出结果。因此重复减半直到达到,(1 >. (<. @ -:)) ^: a: 27产生27127 13 6 3 1

现在让我们看一下钩子的左半部分。 (2&|@] # (2&*~ <@#))是一个二元分叉,参数是ethiop上述钩子的左侧参数和右侧部分的结果。

2&|@]1如果它的正确论点是奇数,0否则。对于论点27 13 6 3 1,结果是1 1 0 1 1

(2&*~ <@#)又是一个钩子。<@# 单子应用于27 13 6 3 1,并将长度框起来,返回(<5)。然后我们得到2&*~,正如我们所看到的,它是二元的,所以这是(在~切换参数之后)+:^:(<5) 12

f^:m,当m被装箱时,会f <: >m产生一个m-length 的结果列表(除非m是空的,在这种情况下它会运行直到收敛)。所以这将产生12 * 2 ^ i.5

然后叉子的中间部分是简单的#,它使用布尔左参数简单地过滤其右参数,在这种情况下,留下 12 * 那些 2 的幂,其中 27 是奇数。

   1 1 0 1 1 # 12 24 48 96 192
12 24 96 192

最后+/sum

   +/12 24 96 192
324
于 2011-09-19T14:33:54.423 回答