2013-04-25 57 views
2

对于项目欧拉问题#1#1,最短的一个班轮在GHCI是:项目欧拉:在Haskell实施

sum [3,6..9999] + sum [5,10..9999] - sum [15,30..9999] 

我发现这个后,我解决了这个问题是一个非常血腥的方式。然而,由于我是Haskell的新手,我决定看看我是否可以将它作为一组返回类似于x的任何值(步长值,即上面的'3'或'5')和。Y(列表的长度)

我都第一个函数在这里完成的。

sumList :: (Enum a, Num a) => a -> a -> a 
sumList a b = sum[a,a+a..b] 

接下来我试图把这个功能和做,例如一些诸如sumListTotals [3,5] 1000从问题那么这一切sumList为列表中的每个项目,然后一个减去重复的数字(即[15,30..1000]使用该示例。

我不是l为某人实际解决问题而提供的帮助,以帮助我指引我走向正确的方向。

我尝试使用map功能类似如下:

sumListTotals list = map f list 
    where f = sumlist a b 

但是,我不知道该如何从列表中拔出的东西,或者如果我这样做sumListTotals ([3,5],1000)或完全对我是这里错了吗?每@ user5402

更新:

module Project1 where 

import Data.List (union) 

sumListTotals :: (Enum a, Eq a, Num a) => a -> a -> a -> a 
sumListTotals a b c = sum $ union [a,(*2)a..c] [b,(*2)b..c] 
+1

对于算法解决方案,请查看[Data.List.union](http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-List.html#v:工会) – ErikR 2013-04-25 02:04:38

+0

嗯......这是一个很酷的功能。 =)..因为我终于有空闲时间了,所以我会尽快发布。 – flamusdiu 2013-04-26 21:25:45

+0

我认为使用'union'是一个更干净/更清晰的解决方案,然后使用where子句。虽然,我不知道如何读取函数的类型信号。我欺骗并用':t'使用ghci来生成sig。 :P – flamusdiu 2013-04-26 21:52:50

回答

1

你在正确的轨道上:

sumListTotals a b c = sum [a,a+a..c] + sum [b,b+b..c] - sum[m,m+m..c] 
    where m = ...???... 

我将离开你要弄清楚的m的定义,因为这是一个真正的数论问题而不是一个Haskell编程问题。

显然对于a = 3, b = 5m应该是15。但m应为a = 3, b = 3

+0

我完全没有意识到你可以像这样的'where'子句。 :P – flamusdiu 2013-04-26 21:26:57

+0

我打算接受这个答案,因为这可以工作,但对于那些正在寻找这个解决方案的人来说:user5402关于使用'Data.List.union'的评论在这个解决方案中效果更好。 – flamusdiu 2013-04-26 21:57:46

+1

请注意,'union'在它的一个参数的长度上占用了二次时间,所以不是实现这个想法的最有效的方法。由于这两个列表都是排序的,并且不包含重复项,因此您只需合并它们即可,只需要线性时间。您可以尝试编写'merge :: [Int] - > [Int] - > [Int]',假设输入列表已经排序。 – ErikR 2013-04-27 04:55:04