Adrian Voicu
Adrian Voicu

Reputation: 23

check if a list has ascending elements - descending elements or descending elements - ascending elements

I'm beginner in Haskell. I have found a problem in a book: Check if a list has aspect of a "mountain", ascending elements - descending elements. Check if a list has aspect of a "valley",descending elements - ascending elements.Please help me.

Exemple:

"Mountain": [1,2,3,4,5,6,3,2,1]

"Valley": [4,3,2,1,1,2,3,4]

My code looks:

  1. Mountain

    ordered::[Int]->Bool
    ordered [a]=True
    ordered (a:l)=if(a>head(l)) then False
              else ordered(l) 
    
  2. Valley

    ordered::[Int]->Bool
    ordered [a]=True
    ordered (a:l)=if(a<head(l)) then False
              else ordered(l) 
    

Upvotes: 1

Views: 638

Answers (3)

Adrian Voicu
Adrian Voicu

Reputation: 23

localMinima :: [Integer] -> Integer
localMinima [x]=x
localMinima (x:xs) = if x<m then x
                 else m where m=localMinima xs


rmAdjacentDups :: [Integer]->[Integer]
rmAdjacentDups []     = []
rmAdjacentDups (x:xs) = x : (rmAdjacentDups $ dropWhile (== x) xs)


isValley :: [Integer] -> Bool
isValley xs = 1 == (length $ localMinima $ rmAdjacentDups xs)

Upvotes: 1

Here's a strategy: a list is a "mountain" if it has only one local maximum once you remove adjacent repeated elements. Likewise, a "valley" is a list that has only one local minimum once adjacent repeated elements are removed. The functions below will tell if a list is a mountain or a valley:

isMountain :: [Integer] -> Bool
isMountain xs = 1 == (length $ localMaxima $ rmAdjacentDups xs)

isValley :: [Integer] -> Bool
isValley xs = 1 == (length $ localMinima $ rmAdjacentDups xs)

*Main> isMountain [1,2,3,4,5,6,3,2,1]
True
*Main> isMountain [1,2,3,4,5,6,5,6,3,2,1]
False
*Main> isValley [4,3,2,1,1,2,3,4]
True
*Main> isValley [4,3,2,1,2,1,1,2,3,4]
False

Leave a comment if you're stuck implementing localMaxima, localMinima or rmAdjacentDups. Hope this helps!

Upvotes: 0

dfeuer
dfeuer

Reputation: 48581

You should start by thinking about the base case. You've started with a base case of a list with 1 element, but there's a simpler base case: the empty list. The empty list is normally considered to be both ascending and descending. The next thing you should do is to quit using head. It's partial, and will lead you into errors. Instead, pattern match everything.

Hint on writing a really simple version, after you write the pattern-matching one: use zipWith and drop. Note that unlike tail, drop is a total function.

Upvotes: 2

Related Questions