如何在J中重构这个?

Jad*_*ias 2 refactoring j tacit-programming

我对Project Euler#1的新手解决方案

+/((0=3|1+i.1000-1) +. (0=5|1+i.1000-1)) * (1+i.1000-1)
Run Code Online (Sandbox Code Playgroud)

我知道这可以重构,转换成一个函数,我不知道该怎么做,我必须阅读所有的实验来学习它.

Tik*_*anz 7

没有必要"处理零",因为添加零不会改变答案,因此您可以使用i.生成低于1000的数字列表,例如:

   i. 10
0 1 2 3 4 5 6 7 8 9
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

|"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
Run Code Online (Sandbox Code Playgroud)

在数组的两个项(行)之间插入OR条件:

  +./ 0 = 3 5 |"0 1 i. 10
1 0 0 1 0 1 1 0 0 1
Run Code Online (Sandbox Code Playgroud)

获取列表/向量中每个1的索引:

  I. +./ 0 = 3 5 |"0 1 i. 10
0 3 5 6 9
Run Code Online (Sandbox Code Playgroud)

总结:

 +/ I. +./ 0 = 3 5 |"0 1 i. 10
Run Code Online (Sandbox Code Playgroud)

23

你可以很容易地将它变成一个明确的函数/动词:

   euler1=: verb define
+/ I. +./ 0 = 3 5 |"0 1 i. y
)
Run Code Online (Sandbox Code Playgroud)

或者一旦你掌握了默契J,你可以定义:

   euler1=: +/@I.@(+./)@(0 = 3 5 |"0 1 i.)
Run Code Online (Sandbox Code Playgroud)