Project Euler#1的新手解决方案
+/((0=3|1+i.1000-1) +. (0=5|1+i.1000-1)) * (1+i.1000-1)
我知道这可以重构,转换成函数,我不知道怎么做,我必须阅读所有的实验来学习它。
答案 0 :(得分:7)
没有必要“处理零”,因为添加零不会改变答案,因此您只需使用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.)
答案 1 :(得分:1)
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
到目前为止,我唯一无法重构的是|
运算符