Sum digits of an integer: Difference between revisions

Content added Content deleted
Line 2,043: Line 2,043:
Or, we could write '''sum . fmap digitToInt''', or the equivalent but more efficient fusion of it to a single fold: '''foldr ((+) . digitToInt) 0'''
Or, we could write '''sum . fmap digitToInt''', or the equivalent but more efficient fusion of it to a single fold: '''foldr ((+) . digitToInt) 0'''
<lang haskell>import Data.Char (digitToInt, intToDigit, isHexDigit)
<lang haskell>import Data.Char (digitToInt, intToDigit, isHexDigit)
import Data.List (transpose, intersperse)
import Data.List (transpose)
import Numeric (showIntAtBase, readInt)
import Numeric (readInt, showIntAtBase)

------------------ SUM OF INTEGER DIGITS -----------------


digitSum :: String -> Int
digitSum :: String -> Int
Line 2,050: Line 2,052:


intDigitSum :: Int -> Int -> Int
intDigitSum :: Int -> Int -> Int
intDigitSum base n = digitSum (showIntAtBase base intToDigit n [])
intDigitSum base =
digitSum
. flip (showIntAtBase base intToDigit) []



-- TESTS ---------------------------------------------------
-------------------------- TESTS -------------------------
main :: IO ()
main :: IO ()
main =
main =
mapM_ putStrLn $
mapM_ putStrLn $
unwords
unwords <$>
transpose
<$> transpose
( ( fmap
((fmap =<< flip justifyRight ' ' . succ . maximum . fmap length) <$>
=<< flip justifyRight ' '
transpose
([ "Base"
. succ
, "Digits"
. maximum
, "Value"
. fmap length
, "digit string -> sum"
)
, "integer value -> sum"
<$> transpose
] :
( [ "Base",
((\(s, b) ->
"Digits",
let v = readBase b s
"Value",
in [ show b -- base
"digit string -> sum",
, show s -- digits
"integer value -> sum"
, show v -- value
] :
, show (digitSum s) -- sum from digit string
( ( \(s, b) ->
, show (intDigitSum b v) -- sum from base and value
let v = readBase b s
]) <$>
in [ show b, -- base
[("1", 10), ("1234", 10), ("fe", 16), ("f0e", 16)])))
show s, -- digits
show v, -- value
-- sum from digit string
show (digitSum s),
-- sum from base and value
show (intDigitSum b v)
]
)
<$> [ ("1", 10),
("1234", 10),
("fe", 16),
("f0e", 16)
]
)
)
)
where
where
justifyRight n c s = drop (length s) (replicate n c ++ s)
justifyRight n c = (drop . length) <*> (replicate n c <>)
readBase b s =
readBase b s = n
where
let [(n, _)] = readInt b isHexDigit digitToInt s
in n</lang>
[(n, _)] = readInt b isHexDigit digitToInt s</lang>
{{Out}}
{{Out}}
<pre> Base Digits Value digit string -> sum integer value -> sum
<pre> Base Digits Value digit string -> sum integer value -> sum