Reputation: 23
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:
Mountain
ordered::[Int]->Bool
ordered [a]=True
ordered (a:l)=if(a>head(l)) then False
else ordered(l)
Valley
ordered::[Int]->Bool
ordered [a]=True
ordered (a:l)=if(a<head(l)) then False
else ordered(l)
Upvotes: 1
Views: 638
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
Reputation: 8069
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
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