'Break an integer to a list of digits
I am learning Haskell, and I am solving problem 30 on project Euler.
digits n = if n<10 then [n] else (digits (quot n 10)) ++ [(mod n 10)]
isP30 n = (sum $ map (^5) $ digits n) == n
sum $ filter isP30 [10^5..10^6-1]
Is there a more readable way to implement the digits function ?
Solution 1:[1]
Using @BenjaminHodgson's suggestion, you can write an unfold as
import Data.Tuple (swap)
import Data.List (unfoldr)
digits = unfoldr go
where go 0 = Nothing
go n = Just (swap $ n `divMod` 10)
However, due to how unfoldr works you will get the digits in reverse order here. Another solution is to ditch this entirely and go with
import Data.Char (digitToInt)
digits = map digitToInt . show
My timings found it to be faster and use about 25% of the memory in an unoptimized GHCi session, it also doesn't reverse the order of the digits.
Solution 2:[2]
What about:
digits n = fmap digitToInt $ show n
I forgot to mention that you need to import digitToInt from Data.Char first, as in @bheklilr's answer.
Solution 3:[3]
First of all it is always more readable to write code with guards, instead of if-then-else. All the extraneous parens are also distracting.
The standard transformation for the inefficient appending-at-end functions, like your
digits n | n < 10 = [n]
| otherwise = digits (quot n 10) ++ [mod n 10]
is to introduce an additional argument, where calling the old digits n ++ xs is the same as calling the new go n xs:
digits n = go n [] -- digits_old n ++ [] == go n []
where
go n next | n < 10 = n : next
| otherwise = go (quot n 10) (mod n 10 : next)
-- [a,b,c,...,x,y] [z]
-- [a,b,c,...,x] [y,z]
Thus the digits being produced in the reversed order go one by one into the result list being built bottom-to-the-top in an accumulator parameter, resulting in the list created in the correct order.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | bheklilr |
| Solution 2 | |
| Solution 3 |
