我对 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

到目前为止我唯一无法重构的是 | 操作员

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top