You probably know about project Euler question 5: get the smallest number divisble by all numbers 1 to 20.
The logic I applied was "start with the first number greater than the largest of the list(20) and also divisible by it which is 40" and stepsize of 20 (largest number)
I did this using list comprehension but it's pretty lame.
pe5 = head [x|x<-[40,60..],x`mod`3==0,x`mod`4==0,x`mod`6==0,x`mod`7==0,x`mod`8==0,x`mod`9==0,x`mod`11==0,x`mod`12==0,x`mod`13==0,x`mod`14==0,x`mod`15==0,x`mod`16==0,x`mod`17==0,x`mod`18==0,x`mod`19==0]
Can we do this better perhaps using zipWith and filter maybe?
Just to clarify, this is not a homework assignment. I'm doing this to wrap my brain around Haskell. (So far I'm losing!)
:Thanx all
I think this is a saner way (there may be thousand more better ways but this would suffice) to do it
listlcm'::(Integral a)=> [a] -> a
listlcm' [x] = x
listlcm' (x:xs) = lcm x (listlcm' xs)
In this particular case, you can get it for free using foldl
and lcm
:
euler = foldl lcm 2 [3..20]
This gives me 232792560 instantaneously.
Since the spoiler has already been posted, I thought I'd explain how it works.
The smallest number divisible by two numbers is also known as the least common multiple of those numbers. There is a function for calculating this in the Prelude.
λ> lcm 10 12
60
Now, to extend this to multiple numbers we exploit the following property
lcm(a1, ... an) = lcm(lcm(a1, ... an-1), an)
In Haskell, f(f(... f(a1, a2), ...), an) can be written foldl1 f [a1, a2, ... an]
, so we can solve the problem with this simple one-liner:
λ> foldl1 lcm [1..20]
232792560
This finds the solution in a fraction of a second.
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