Is there any way to find out local maxima of a list using foldr
or foldl
or maybe I have to use unfoldr
because of first and last elements of list aren't local maximums?
I understand how to find it using recursion with guards, e.g.
localMax :: [Int] -> [Int]
localMax [] = []
localMax (x:[]) = []
localMax (x:y:[]) = []
localMax (x:y:z:zs)
| y > z && y > x = y:localMax (y:z:zs)
| otherwise = localMax (y:z:zs)
You could, but itd be very ugly. Mostly because to find the local maximum, you'll need to know the previous and next elements.
The previous element is no problem, but a fold isn't supposed to know anything about the elements after it.
As a possible approach
import Data.List (zip3)
localMax xs = map proj2
. filter isLocalMax
$ zip3 xs (tail xs) (drop 2 xs)
where isLocalMax (x, y, z) = x < y && z < y
proj2 (_,x,_) = x
So we shift the list by one and two and zip it all together so [a, b, c, d, e]
becomes
[(a, b, c), (b, c, d), (c, d, e)]
then we just use map
and filter
to select the appropriate elements.
Do note though that map
and filter
could be smashed into one foldr
if you really wanted to.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With