Just for fun, I thought I'd throw together a solution with a very different flavor. Imagine for a moment that instead of a list of numbers, we had a string with an L
when the numbers decreased, an E
when they stayed the same, or a G
when they got bigger. Then being triangular means testing whether that string is in the regular language [LE]*[GE]*
. So that's what we'll do in this solution: write a regex and check whether the numbers' summary matches it. I'm using regex-applicative, but you can use your favorite regex library instead if you like.
{-# LANGUAGE NoMonomorphismRestriction #-}
import Data.Maybe
import Text.Regex.Applicative
triangular = many (sym LT <|> sym EQ) *> many (sym GT <|> sym EQ)
summarize xs = zipWith compare xs (tail xs)
ex = isJust . match triangular . summarize
We can try it on all your examples in ghci:
*Main> map ex [[2,4,5,7,4,3], [], [1], [1, 2, 3], [3, 2, 1], [1, 2, 2], [2, 2, 1]]
[True,True,True,True,True,True,True]
*Main> ex [2,3,4,3,2,3,4] -- plus one I made up to check it's not const True
False