4
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]))

我正在学习 Haskell,希望你不介意我问这个。有没有更好的方法来获得一个包含 3 或 5 倍数的低于 1000 的所有自然数的列表?(例如使用 zip 或地图?)

编辑:

import Data.List

euler :: Int
euler = sum (union [3,6..999] [5,10..999])

谢谢你们的帮助,伙计们。

4

7 回答 7

15

使用列表理解:

sum [x | x <- [1..999], x `mod` 3 == 0 || x `mod` 5 == 0]
于 2012-08-16T07:35:22.553 回答
10

您也可以使用硬编码版本:

sum $ [3, 6 .. 999] ++ [5, 10 .. 999] ++ [-15, -30 .. -999]
于 2012-08-16T11:01:21.920 回答
8

这将为您提供您要求的列表:

filter (\x -> (x `mod` 3 == 0) || (x `mod` 5 == 0)) [1..999]
于 2012-08-16T07:37:29.957 回答
5

这是一个。

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

这是另一种效率较低的方法:

import Data.List

nub . sort $ ([3,6..999] ++ [5,10..999])

(如果我们有 import 语句,我们不必使用完全限定的名称)。

同样有趣的是找到只有3 和 5 的倍数:

m35 = 1 : (map (3*) m35 `union` map (5*) m35)
于 2012-08-16T07:38:22.657 回答
2
sum [x | x <- [1..999], let m k = (x`mod`k==0), m 3 || m 5]
于 2012-08-16T22:36:21.957 回答
1

一个更通用的数字列表解决方案,而不仅仅是 3 和 5:

addMultiples :: [Int] ->  Int -> Int
addMultiples multiplesOf upTo = sum[n | n <- [1..upTo-1], or (map ((0==) . mod n) multiplesOf)]
于 2012-12-17T23:03:24.323 回答
1

这是一个超快的。尝试价值超过 10 亿美元。

eu x = sum[div (n*(p*(p+1))) 2 | n<-[3,5,-15], let p = div (x-1) n]

我想它可以进一步缩短。

于 2013-01-31T06:39:28.550 回答