我对 Project Euler #1 的新手解决方案
+/((0=3|1+i.1000-1) +. (0=5|1+i.1000-1)) * (1+i.1000-1)
我知道这可以重构,并转换成一个函数,我不知道该怎么做,我必须阅读所有的实验室来学习它。
我对 Project Euler #1 的新手解决方案
+/((0=3|1+i.1000-1) +. (0=5|1+i.1000-1)) * (1+i.1000-1)
我知道这可以重构,并转换成一个函数,我不知道该怎么做,我必须阅读所有的实验室来学习它。
没有必要“处理零”,因为添加零不会改变答案,因此您可以使用i.
生成低于 1000 的数字列表,例如:
i. 10
0 1 2 3 4 5 6 7 8 9
J 最适用于数组,因此您应该能够同时请求|
3 和 5 的余数 ( ),您可以使用 rank ( "
) 来控制如何将参数馈送到残差:
3 5 |"0 1 i. 10
0 1 2 0 1 2 0 1 2 0
0 1 2 3 4 0 1 2 3 4
说要一次将|"0 1
左参数提供给|
一个项目,而一次将右参数提供给一行。因为右边的参数只包含一行,所以它被重复地馈送到每个左边的参数项。
现在我们可以0=
对整个数组执行以下操作:
0 = 3 5 |"0 1 i. 10
1 0 0 1 0 0 1 0 0 1
1 0 0 0 0 1 0 0 0 0
在数组的两项(行)之间插入 OR 条件:
+./ 0 = 3 5 |"0 1 i. 10
1 0 0 1 0 1 1 0 0 1
获取列表/向量中每个 1 的索引:
I. +./ 0 = 3 5 |"0 1 i. 10
0 3 5 6 9
和总和:
+/ I. +./ 0 = 3 5 |"0 1 i. 10
23
你可以很容易地使它成为一个显式的函数/动词:
euler1=: verb define
+/ I. +./ 0 = 3 5 |"0 1 i. y
)
或者,一旦你掌握了默认 J 的窍门,你就可以定义:
euler1=: +/@I.@(+./)@(0 = 3 5 |"0 1 i.)
0=
(将增加程序大小)+/((3|1+i.1000-1)+.&(0=])5|1+i.1000-1)*1+i.1000-1
1+i.1000-1
+/(((3|])+.&(0=[)5|])1+i.1000-1)*1+i.1000-1
1+i.1000-1
再次重构+/(*(3|])+.&(0=[)5|])1+i.1000-1
到目前为止我唯一不能重构的是|
操作符