如何在 J 中重构它?
-
21-09-2019 - |
题
我对 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
Ĵ效果最佳阵列,所以你应该能够要求3和5中的残余物(|
)的同时,可以使用秩("
),以控制如何将参数输送到残余物:
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
说喂左边参数,同时将右参数的行-AT-A-时间|
一个项目-AT-A-时间。因为右参数只由一个线,它被重复地馈送到每一个左参数项目。
现在我们可以做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
到目前为止我唯一无法重构的是 |
操作员
不隶属于 StackOverflow