1

Few weeks ago I had a task to accomplish and my way of thinking is correct, but the implementation I gave at that time was horrible. I have a chance to get some points but only if I provide a correct implementation. The problem is:

Consider a list of integers [x_1; x_2;...;x_n]. We'll call index i "a hole" if 1 < i < n, such as x_i < max(x_1,...,x_{i-1}) and x_i < max(x_{i+1},...,x_n). The depth of this hole is min(max(x_1,...,x_{i-1})-x_i, max(x_{i+1},...,x_n)-x_i).

Write procedure hole : int list -> int which for given list of integers find the max depth on this list. If there is no hole on the list, then the correct answer is 0. For example: hole [5;2;7;10;3;7] = 3, because for i=2, max on the left is 5, max on the right is 10, min (5 - 2, 10-2) = 3. hole [1;2;3;2;1] = 0, because there is no such index i, that matches our predicate.

Now, my procedure looks like this with using recursion:

let hole list =
   let rec aux maxL acc = function
    | [] -> (min_int, [])
    | x::xs ->
        let newMax = max maxL x in
        let (maxR, aclist) = aux newMax acc xs
        in
            if maxL > x && x < maxR then (max maxR x,(min (maxL-x) (maxR-x))::aclist)
            else (max maxR x, aclist)
in fold_left max 0 (snd (aux min_int [] list))

but I have to make it without using recursion, while I'm able to use high order functions. I wanted to use something called "function accumulation", but I can't get any idea on how to do it (been thinking about this problem for over 7 hours now).

Any code given in Haskell/OCaml is welcome. The only problem is that you CANNOT use recursion.

4
  • I am still considering that list. Was there something you wanted me to do with it? Commented Dec 1, 2014 at 4:38
  • I'm not sure what you are asking. I can't understand from the snippet of the problem what the function is supposed to do or even what type it should have. The provided code is supposedly not a "correct implementation". Can you please describe the function you are looking for, and perhaps include some sample inputs and the corresponding result? Commented Dec 1, 2014 at 4:53
  • 1
    "Write procedure "hole : int list -> int" which for given list of integers find the max depth on this list. If there is no hole on the list, then the correct answer is 0. For example: hole [5;2;7;10;3;7] = 3, because for i=2, max on the left is 5, max on the right is 10, min (5 - 2, 10-2) = 3. hole [1;2;3;2;1] = 0, because there is no such index i, that matches our predicate. Commented Dec 1, 2014 at 6:19
  • 2
    Isn't the 3 at position 5 in your list a deeper hole? Commented Dec 1, 2014 at 6:31

1 Answer 1

1

Here is code that may do what I think you are looking for, i.e. find the depth of the deepest 'hole' in a list of integers according to your description of a 'hole'. It zips up left and right scans for max with a list of the 'middle' values, which could be described with the word 'accumulating' if you want.

Not the most efficient implementation, I'm sure, but I think it is better than the obvious brute force solution. Where no hole is found, it returns Nothing.

deepestHole' :: [Int] -> Maybe Int
deepestHole' xs 
  | length xs < 3 = Nothing
  | maxHole < 1 = Nothing
  | otherwise = Just maxHole
  where
    lMaxes = scanl1 max $ take (length xs - 2) xs
    rMaxes = scanr1 max (drop 2 xs)
    middles = tail $ init xs
    holeDepth lMax mid rMax = min lMax rMax - mid
    maxHole = maximum $ zipWith3 holeDepth lMaxes middles rMaxes
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.