I'm looking for feedback on my solution to the following prompt:
Given an array of ints, return the index such that the sum of the elements to the right of that index equals the sum of the elements to the left of that index. If there is no such index, return Nothing. If there is more than one such index, return the left-most index. Example:
peak([1,2,3,5,3,2,1]) = 3
, because the sum of the elements at indexes 0,1,2 == sum of elements at indexes 4,5,6. We don't sum index 3.
Questions:
- Is the solution best defined recursively? Or is there some kind of higher-order function that I could use?
- The function
peak'
takes four arguments. That feels a little unwieldy. Any reasonable way to shorten that parameter list? - Conventional programming wisdom says to avoid "magic numbers", so I introduced some bindings in the
let
clause. Does that makepeak
easier to read, or does it just seem like bloat?
peak :: [Int] -> Maybe Int
peak numbers =
let leftSum = 0
rightSum = sum numbers
startingIndex = 0
in peak' numbers leftSum rightSum startingIndex
peak' :: [Int] -> Int -> Int -> Int -> Maybe Int
peak' [] _ _ _ = Nothing
peak' (x:xs) leftSum rightSum index
| leftSum + x == rightSum = Just index
| otherwise = peak' xs (leftSum + x) (rightSum - x) (index + 1)
Prompt source: https://www.codewars.com/kata/5a61a846cadebf9738000076/train/haskell