Balanced number checking

Problem

Balanced number is the number that the sum of all digits to the left of the middle digit(s) and the sum of all digits to the right of the middle digit(s) are equal. The middle digit(s) should not be considered when determining whether a number is balanced or not.

If the number has an odd number of digits then there is only one middle digit, e.g. 92645 has middle digit 6; otherwise, there are two middle digits , e.g. 1301 has middle digits 3 and 0.

Given a number, find if it is balanced or not. Number passed is always Positive. Return the result as String.

My solution

I solved it. But I am not sure, how to fold the similarly looking code for odd and even lengths.

data ListLength a = ListLength {list :: [a], len :: Int} deriving Show

digs :: Integral x => x -> ListLength x
digs 0 = ListLength  1
digs x = let
helper :: Integral x => x -> [x] -> Int -> ListLength x
helper 0 acc len = ListLength acc len
helper n acc len = helper (n div 10) ((n mod 10) : acc) $len + 1 in helper x [] 0 balancedNum :: Int -> String balancedNum n | n > 0 = let digits = digs n middle = (len digits) div 2 in if even (len digits) then let (left, right) = splitAt (middle - 1) (list digits) in if (sum left) == (sum$ drop 2 right) then
"Balanced"
else
"Not Balanced"
else
let (left, right) = splitAt middle (list digits) in
if (sum left) == (sum $tail right) then "Balanced" else "Not Balanced" | otherwise = error "Number must be positive" 1 Answer Here my thoughts on your solution. But I'm also learning Haskell right now, so I'm not an expert.. You don't need the data type. You can use base 10 logarithm to get the number of digits. Like this: (floor$ logBase 10 $fromIntegral n) + 1 I like the fact that digs is tail recursive. It looks simpler without the data type: digits :: Int -> [Int] digits = digits_tr [] where digits_tr :: [Int] -> Int -> [Int] digits_tr l 0 = l digits_tr l n = digits_tr (n mod 10 : l) (n div 10) Why does balancedNum give a string? A boolean would be more natural. If you want to handle errors, why not use Maybe instead of error? Like in balancedNum :: Int -> Maybe Bool. Anyway according to the problem description you wouldn't need it: a negative number is just not balanced, so the function should just give False back. Here is my solution: balanced :: Int -> Bool balanced n | n >= 0 = (sum$ take middle $digits n) == (sum$ take middle $reverse$ digits n)
| otherwise = False
where
len = (floor $logBase 10$ fromIntegral n) + 1
middle = if len mod 2 == 0 then len div 2 - 1 else len div 2
• "You can use base 10 logarithm to get the number of digits." - this is a good option. On the other hand we can skip the logarithm calculation, using some memory for storage. We are traversing the list anyway. Feb 10 '20 at 19:45
• "Why does balancedNum give a string? A boolean would be more natural." - I agree, but this was the exercise condition. Feb 10 '20 at 19:49
• Oh, there is an error in this solution: balanced 56239814 returns False, while it it should return True. Feb 10 '20 at 20:12
• You're right: round after the logarithm was wrong (and didn't make sense). Now it should work. Feb 11 '20 at 17:50