将我的第一个J程序写入解算器Euler problem #1(找到1000以下的所有自然数之和为3或5的倍数),我得到了以下解决方案:
+/(+./0=3 5|/n)#n=.i.1000
但是,我非常确定有一种聪明的方法,不使用变量。我尝试使用fork重写它,但我不知道如何将()作为应用于3 5
和i.1000
的动词之间的表达式替换。有人能帮助我吗?
答案 0 :(得分:3)
要对两个值进行参数化,从而推广到二元动词,我们需要将每个参数传递到需要它们的位置。我们可以专注于从这个fork开始实际需要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([
)具有与先前版本中相同的值,当它引用最外层的参数时。在这个新动词中,右(]
)指的是整数列表,发生在i.@]
之前出现的两个地方。
后记:正如您在评论中所示,[ |/ ]
已简化为|/