项目欧拉:解决问题#5的一个(更好的)方法?

fed*_*asu 4 haskell

你可能知道项目欧拉问题5:得到所有数字1到20的最小数字.

我应用的逻辑是"从第一个数字开始,大于列表中最大的数字(20),也可以被40整除,步长为20(最大数字)

我使用列表理解做到了这一点,但它非常蹩脚.

pe5 = head    [x|x<-[40,60..],x`mod`3==0,x`mod`4==0,x`mod`6==0,x`mod`7==0,x`mod`8==0,x`mod`9==0,x`mod`11==0,x`mod`12==0,x`mod`13==0,x`mod`14==0,x`mod`15==0,x`mod`16==0,x`mod`17==0,x`mod`18==0,x`mod`19==0] 
Run Code Online (Sandbox Code Playgroud)

我们可以更好地使用zipWith和过滤器吗?

只是为了澄清,这不是一项家庭作业.我这样做是为了将我的大脑包裹在Haskell周围.(到目前为止我输了!)

:Thanx all

我认为这是一种更为理智的方式(可能还有更多方法,但这就足够了)

listlcm'::(Integral a)=> [a] -> a
listlcm' [x] = x
listlcm' (x:xs) = lcm x (listlcm' xs)  
Run Code Online (Sandbox Code Playgroud)

小智 12

在这种特殊情况下,您可以使用foldl和免费获得它lcm:

euler = foldl lcm 2 [3..20]
Run Code Online (Sandbox Code Playgroud)

这瞬间给了我232792560.

  • 甚至更短:`foldl1 lcm [2..20]` (3认同)

ham*_*mar 6

由于扰流板已经发布,我想我会解释它是如何工作的.

可被两个数字整除的最小数字也称为这些数字的最小公倍数.在Prelude中有一个计算此功能的功能.

?> lcm 10 12
60
Run Code Online (Sandbox Code Playgroud)

现在,为了将其扩展为多个数字,我们利用以下属性

lcm(a 1,... a n)= lcm(lcm(a 1,... a n-1),a n)

在Haskell中,f(f(... f(a 1,a 2),...),a n)可以写成,所以我们可以用这个简单的单行解决问题:foldl1 f [a1, a2, ... an]

?> foldl1 lcm [1..20]
232792560
Run Code Online (Sandbox Code Playgroud)

这可以在几分之一秒内找到解决方案.

  • @Vasu:也许是初学者,但是当标准的高阶函数之一完成工作时,它通常被认为是编写自己的递归的反模式.虽然有些情况会导致代码的可读性降低,但这并非如此. (3认同)