0

编写我的第一个 J 程序来求解欧拉问题 #1(找到所有低于 1000 且是 3 或 5 的倍数的自然数之和),我得到了以下解决方案:

+/(+./0=3 5|/n)#n=.i.1000

但是,我很确定有一种巧妙的方法可以做到这一点,而无需使用变量。我尝试使用 fork 重写它,但我不知道如何将 () 之间的表达式替换为应用于3 5and的动词i.1000。有人可以帮助我吗?

4

1 回答 1

3

为了参数化这两个值,从而泛化为二元动词,我们需要将每个参数传递到需要它们的地方。从这个分叉开始,我们可以专注于3 5实际需要的唯一点:

   3 5 ([ |/ i.@]) 1000

在整个程序中,我们需要两个地方的整数列表。名称 ( n) 为我们提供了在两个地方使用该列表的简单方法。为了快速完成整个程序,在写这篇文章时,我最初计算了两次列表:

   3 5 ([: +/ i.@] # [:+./ 0= [ |/ i.@]) 1000

i.这成功地将整个程序表述为二元动词,但出现两次也有缺点。我们可以通过将其设为正确的叉齿,将其提取为仅发生一次。那个叉子的中心是一个新的、内在的动词。

   3 5 ([: +/ [ (] # [:+./ 0= [ |/ ]) i.@]) 1000
NB.              ___________________             new "inner" verb, parenthesized

这个内在动词需要接收3 5作为参数,所以我通过最外层动词的左参数作为这个内在动词的左参数。这意味着内部动词中的 Left ( [) 与之前版本中的值相同,当它引用最外层参数时。在这个新动词中 Right ( ]) 指的是整数列表,i.@]出现在之前出现的两个地方。

后记:正如您在评论中显示的那样,[ |/ ]简化为|/

于 2013-02-28T20:22:56.723 回答