首页 文章

项目Euler#1使用Haskell

提问于
浏览
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的倍数? (例如带拉链或 Map ?)

编辑:

import Data.List

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

伙计们,感谢您的帮助 .

7 回答

  • 10

    使用列表理解:

    sum [x | x <- [1..999], x `mod` 3 == 0 || x `mod` 5 == 0]
    
  • 1

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

    sum $ [3, 6 .. 999] ++ [5, 10 .. 999] ++ [-15, -30 .. -999]
    
  • 8

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

    filter (\x -> (x `mod` 3 == 0) || (x `mod` 5 == 0)) [1..999]
    
  • 15

    这是一个 .

    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)
    
  • 2
    sum [x | x <- [1..999], let m k = (x`mod`k==0), m 3 || m 5]
    
  • 1

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

    addMultiples :: [Int] ->  Int -> Int
    addMultiples multiplesOf upTo = sum[n | n <- [1..upTo-1], or (map ((0==) . mod n) multiplesOf)]
    
  • 5

    这是超快速的 . 尝试使用超过十亿的 Value .

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

    我想它可以进一步缩短 .

相关问题