Niedawno zapoznałem się z przewodnikiem „ Naucz się świetnego dobrego Haskella” i jako praktykę chciałem rozwiązać z nim problem dotyczący projektu Euler 5 , który określa:
Jaka jest najmniejsza liczba dodatnia, która jest równomiernie podzielna przez wszystkie liczby od 1 do 20?
Postanowiłem najpierw napisać funkcję określającą, czy daną liczbę można podzielić przez te liczby:
divisable x = all (\y -> x `mod` y == 0)[1..20]
Następnie obliczyłem najmniejszy, używając head
:
sm = head [x | x <- [1..], divisable x]
I w końcu napisał wiersz, aby wyświetlić wynik:
main = putStrLn $ show $ sm
Niestety zajęło to około 30 sekund. Robienie tego samego z liczbami od 1 do 10 daje wynik niemal natychmiast, ale z drugiej strony wynik jest znacznie mniejszy niż rozwiązanie dla 1 do 20.
Rozwiązałem go wcześniej w C i tam wynik dla 1 do 20 został również obliczony prawie natychmiast. To prowadzi mnie do wniosku, że nie rozumiem, jak interpretować ten problem dla Haskella. Przejrzałem rozwiązania innych ludzi i znalazłem to:
main = putStrLn $ show $ foldl1 lcm [1..20]
To prawda, wykorzystuje to wbudowaną funkcję, ale dlaczego wynik końcowy jest o wiele wolniejszy, gdy robisz to sam? Tamte tutoriale pokazują, jak używać Haskell, ale nie widzę wiele pomocy w przekształcaniu algorytmów w szybki kod.