刚从Haskell开始,我整理了这个丑陋的部分,以确定列表中的数字可被数字整除,所有数字均小于该数字。

divis :: (Integral a) => a -> [a] -> [a]
divis _ [] = []
divis n (x:xs)
    | x `mod` n == 0 && n == 2 = x : divis n xs
    | x `mod` n == 0 = divis (n-1) [x] ++ divis n xs
    | otherwise = divis n xs

我可以这样称呼它...
head (divis 10 [1..])

以获得列表中的第一个数字,在这种情况下为2520。但是,这似乎不足以有效地解决使用20这样的更高数字。

如何解决haskell的问题?

最佳答案

这可以通过使用不同的算法得到显着改善:可以用一组数字除以的最小数(在这种情况下,该数为[1..10])是这些数字的最小公倍数。

Haskell甚至具有内置的最不常用的多功能(lcm),您可以使用:

Prelude> foldl lcm 1 [1..10]
2520

如果您不想使用内置的lcm函数(因为这几乎是作弊的:)),则可以使用Euclid's algorithm计算GCD,然后使用:
lcm a b = a * b `div` gcd a b

如果需要找到给定列表中所有可被[1..n]整除的数字,则可以使用以下事实:任何此类数字也可被[1..n]的最小公倍数整除:
divis n xs = filter (\x -> x `mod` mult == 0) xs
    where mult = foldl lcm 1 [1..n]

10-02 04:05