Just starting with Haskell, and I put together this ugly piece to determine the numbers in a list divisible by a number and all numbers less than it.
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
and I can call it like...
head (divis 10 [1..])
to get the first number in the list, in this case 2520. However, it seems that this is not good enough to efficently solve using a higher number like 20.
How can I fix this raskell of a haskell?
This can be improved substantially by using a different algorithm: The smallest number which can be divided by a set of numbers (in this case, the set is [1..10]) is the least common multiple of those numbers.
Haskell even has a least common multiple function (lcm
) built-in which you can use:
Prelude> foldl lcm 1 [1..10]
2520
If you prefer not to use the build-in lcm function (as that's almost cheating :) ), you can do it by using Euclid's algorithm to calculate the GCD, and then using:
lcm a b = a * b `div` gcd a b
If you need to find all the numbers in a given list which are divisible by [1..n], you can use the fact that any such number will also be divisible by the least common multiple of [1..n]:
divis n xs = filter (\x -> x `mod` mult == 0) xs
where mult = foldl lcm 1 [1..n]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With