Going through Project Euler I am comparing my solutions to the ones here.
For question 8 my code produces the correct answer (confirmed via the check sum on the website)
What is happening is that digitToInt
returns an Int
, which on 32-bit systems is too short to hold the test numbers when 5 is increased to 13. Change it to (fromIntegral . digitToInt)
and it works correctly.
The problem was already identified as an Int overflow, but the wiki code itself is incorrect. It doesn't truncate the list properly, and might produce incorrect result, depending on input data (i.e. it produces the correct result here by a lucky chance).
Imagine a string of digits which ends in a 0
followed by 12 9
s. The code will take 9^12
into consideration incorrectly, when calculating the maximum value. Even simpler, for a 1000 zeroes it will produce 1 as an answer.
We can achieve an automagical truncation, due to the properties of zipping:
import Data.Char
import Data.List
euler_8 = do
str <- readFile "numbers.txt"
print . maximum . map product
. foldr (zipWith (:)) (repeat []) -- here
. take 13 . tails . map (fromIntegral . digitToInt)
. concat . lines $ str
Your code though is correct, but has some issues:
[x | x <- xs]
is just xs
last (sort xs)
is just maximum xs
, which is fastertoDigits n xs -- to be called as `toDigits n []`
| n < 1 = xs
| otherwise = toDigits (n `div` 10) ((n `mod` 10) : xs)