Gần đây tôi đã trải qua Hướng dẫn tìm hiểu về bạn rất tốt và vì thực tế tôi muốn giải quyết vấn đề Project Euler 5 với nó, trong đó chỉ rõ:
Số dương nhỏ nhất chia hết cho tất cả các số từ 1 đến 20 là bao nhiêu?
Trước tiên tôi quyết định viết một hàm xác định xem một số đã cho có chia hết cho các số này không:
divisable x = all (\y -> x `mod` y == 0)[1..20]
Sau đó, tôi tính toán nhỏ nhất bằng cách sử dụng head
:
sm = head [x | x <- [1..], divisable x]
Và cuối cùng đã viết dòng để hiển thị kết quả:
main = putStrLn $ show $ sm
Thật không may, điều này mất khoảng 30 giây để hoàn thành. Làm điều tương tự với các số từ 1 đến 10 mang lại kết quả gần như ngay lập tức, nhưng sau đó, kết quả lại nhỏ hơn nhiều so với giải pháp cho 1 đến 20.
Tôi đã giải quyết nó sớm hơn trong C và kết quả từ 1 đến 20 cũng được tính gần như ngay lập tức. Điều này khiến tôi tin rằng tôi đang hiểu sai cách giải thích vấn đề này cho Haskell. Tôi đã xem qua các giải pháp của người khác và thấy điều này:
main = putStrLn $ show $ foldl1 lcm [1..20]
Đủ công bằng, điều này sử dụng một chức năng tích hợp, nhưng tại sao kết quả cuối cùng lại chậm hơn rất nhiều khi tự làm điều đó? Các hướng dẫn ngoài kia cho bạn biết cách sử dụng Haskell, nhưng tôi không thấy nhiều trợ giúp với việc chuyển đổi thuật toán thành mã nhanh.