3

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

+/((0=3|1+i.1000-1) +. (0=5|1+i.1000-1)) * (1+i.1000-1)

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

4

2 回答 2

9

没有必要“处理零”,因为添加零不会改变答案,因此您可以使用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.)
于 2011-10-01T03:36:32.753 回答
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

到目前为止我唯一不能重构的是|操作符

于 2009-10-12T18:30:19.380 回答