(2&*~) 15 7 3 1
以上是这句话。最后是追踪和最终结果。我明白这个短语是monad,我明白因为它有左右参数。如果您运行'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&gt;。&lt;。@ - :)^:27返回一个自己的盒子版本,我希望它能运行27次。
关于三个相关问题的最后一个问题(这些问题都与分解道德繁殖代码有关),完整代码如下:
double =: 2&*
halve =: %&2 NB. or the primitive -:
odd =: 2&|
ethiop =: +/@(odd@] # (double~ <@#)) (1>.<.@halve)^:a:
这可以简单地替换为:
ethiop =: +/@(2&|@] # (2&*~ <@#)) (1>.<.@-:)^:a:
这很好用!成功冲了过去,当我想到时,我完全脱离悬崖,在命令行上有一个monadic double:
+: 98
196
并且双精度运算符必须比带有附加常量的双精度运算快,可能是双精度变换,所以我认为
ethiop =: +/@(2&|@] # (+:~ <@#)) (1>.<.@-:)^:a:
会工作......但事实并非如此。
我已经尝试了大写字母,连词等等,没有任何东西能让它发挥作用,它总是说,“域名错误”。我开始认为代码依赖于被称为monad的二元组,以一种我无法获得的方式创建双倍表。
唯一的好处是J动词奇数与测试奇数无关。
任何人都可以向我解释这些事情,也许可以通过英语解释该程序的工作原理吗?不是算法如何工作,它是如何实现算法的。我记得1970年我在玩IBM 1130 APL的时候。这是一个8k字的APL翻译,不用说,它是有限的。例如,它有一个滚动但没有交易。解释器自行进出内存,1130支持代码覆盖,它将子程序分成组,当一个组调用另一个组时,它会将新组加载到磁盘上(是的,在8k中进行伪交换)。因此,我使用各种方案编写了交易的版本,并且随机地,我们会找到一个可以逐步进入和退出而无需寻找的版本,无论多少行编写多少行以及多少次解释器操作将运行10次像其他任何一样快。我不知道我在做什么,我会继续添加ravels和毫无意义的任务,并在各行之间打破语句或将它们组合起来,直到我得到一个不用寻求的方式运行。 (正在寻求的52 52交易可能需要45秒)。
然后昨晚我在J.计算了第150,000个Fibonacci数字。它必须是64位版本,花了一个小时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
Fibonacci脚注:
]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
答案 0 :(得分:5)
答案记录在Bond (&)下,其中注明了以下身份用于二元使用:
x m&amp; v y↔m&amp; v ^:x y
在您的示例中,m为2
,v为*
,x和y均为四个数字15 7 3 1
的列表。
等式右侧的措辞包括^:x
(“对权力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
同样的事情正在发生,它只是更频繁地发生,因为你给出了更高的数字。
答案 1 :(得分:2)
这只是对你的问题的初步尝试,因为到目前为止还没有人回复:
副词早就离开了范围:
(2&*~) <-> ((2&*)~)
bond返回的函数的二元情形是 powered :
(x m&v y) <-> ((m&v)^:x y)
2&*
每次应用时都会将其参数加倍,因此2&*
将其参数乘以2
的幂。
(1>.<.@-:)^: 27
定义一个动词(因为^:
是一个连词),但不会运行它。原始短语foo^:a:
是动词,27
是参数。当a:
是^:
的正确参数时,它会一直运行直到收敛。
Monadic +:
将其论点加倍,但2&*
和+:
的二元案例无论如何都无关,也无法互换。请注意,double~
是钩子的左侧,它总是被称为二元组。
唯一的好处是J动词奇数与测试奇数无关。
实际上,如果2&| y
是奇数,1
是y
,如果是偶数,则0
是12 ethiop 27
,所以它是奇数的测试。
现在,为了尝试用简单的英语解释算法在做什么,让我们一个字一个地看一下,以+/@(2&|@] # (2&*~ <@#)) (1>.<.@-:)^:a:
为例:
(1 >. (<. @ -:)) ^: a:
是一个钩子。在钩子中,右边的部分总是一个单子,左边的部分总是一个二元组。
(<. @ -:)
Monad floor @ half
= 1 >. (<. @ -:
,将其参数减半并向下舍入,然后1
返回其中的最小值^:a:
。 (1 >. (<. @ -:)) ^: a: 27
一直持续到收敛并列出结果列表。因此27
1
重复减半,直至达到27 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)
再次成为一个钩子。 &lt; @#单独应用于2&*~
,并填充长度,返回~
。然后我们到达+:^:(<5) 12
,正如我们所看到的那样,是二元的,所以这是(在f^:m
切换参数后)m
。
f
装箱时, <: >m
执行m
m
次,产生12 * 2 ^ i.5
长度的结果列表(除非#
是空的,在这种情况下它会一直运行直到收敛)。所以这将产生 1 1 0 1 1 # 12 24 48 96 192
12 24 96 192
然后fork的中间部分只是+/
,它带有一个布尔左参数只是过滤其右参数,在这种情况下留下12 *那些2的幂,其中27是奇数。
sum
最后 +/12 24 96 192
324
是{{1}}
{{1}}