Project Euler #1 using Haskell
1 2 3 4 5 6 7
| import Data.Set
euler :: Int
euler = sum [ x | x <- nums ]
where
nums = Data.Set.toList (Data.Set.union (Data.Set.fromList [3, 6.. 999])
(Data.Set.fromList [5, 10.. 999])) |
我在学哈斯克尔,希望你不要介意我问这个问题。有没有更好的方法可以得到一个包含1000以下所有自然数的列表,这些自然数是3或5的倍数?(例如,带拉链还是地图?)
编辑:
1 2 3 4
| import Data.List
euler :: Int
euler = sum (union [3, 6.. 999] [5, 10.. 999]) |
谢谢你们的帮助,伙计们。
- 数据ordlist:data.list.ordered.union;也[x | x <- nums]冰,spelled nums更好。
- 第一,它看起来丑陋的,愚蠢的,现在我感觉很好。欧拉= sum(3.6 ..999联盟[ ] [ ] 5、10 ..999)的作品。谢谢,伙计们。
- 不,Data.List.union冰低效,二次时间复杂性。
使用列表理解:
1
| sum [x | x <- [1.. 999], x ` mod` 3 == 0 || x ` mod` 5 == 0] |
- 总和[n n<-[0..999],m<-[3,5],n modm==0]-(可能更好/更短)
- @如果这就是你的意思?本汇编:sum[n n<-[1..999],m<-[3,5],n modm==0]但由于数字是3和5的倍数(例如15)的条件,回答错误。我喜欢你的想法。啊,国防部周围的这个接口中缺少'
您也可以使用硬编码版本:
1
| sum $ [3, 6 .. 999] ++ [5, 10 .. 999] ++ [-15, -30 .. -999] |
- 双加好,如果你问我!包括排除原则在行动中。
- 或者稍微少一点的硬编码:solve a b n = sum $ [a, a*2 .. n] ++ [b, b*2 .. n] ++ [-(a*b), -(a*b*2) .. -n]。
- 聪明,但对于手头的简单问题过于复杂。
- 这是不太复杂的解决方案编程。数学也很简单。
这将为您提供所需的列表:
1
| filter (\x -> (x ` mod` 3 == 0) || (x ` mod` 5 == 0)) [1.. 999] |
这里有一个。
1 2 3 4 5 6 7 8
| mults35 = union [3, 6.. 999] [5, 10.. 999]
where
union (x :xs ) (y :ys ) = case (compare x y ) of
LT -> x : union xs (y :ys )
EQ -> x : union xs ys
GT -> y : union (x :xs ) ys
union xs [] = xs
union [] ys = ys |
这是另一种效率较低的方法:
1 2 3
| import Data.List
nub . sort $ ([3,6..999] ++ [5,10..999]) |
(如果有import语句,则不必使用完全限定名)。
另一个有趣的是找到只有3和5的倍数:
1
| m35 = 1 : (map (3*) m35 `union` map (5*) m35 ) |
1
| sum [x | x <- [1.. 999], let m k = (x` mod`k ==0), m 3 || m 5] |
这是一个非常快的。试试价值超过10亿美元。
1
| eu x = sum[div (n *(p *(p +1))) 2 | n <-[3, 5, -15], let p = div (x -1) n ] |
我想它可以进一步缩短。
一个更通用的数字列表解决方案,而不仅仅是3和5:
1 2
| addMultiples :: [Int] -> Int -> Int
addMultiples multiplesOf upTo = sum[n | n <- [1..upTo -1], or (map ((0==) . mod n ) multiplesOf )] |