import Data.List import Data.Ord meetTwice f g a b = length [x | x <- [a..b], f x == g x] > 1 mixed f g a b = all (\op -> any (\x -> f x `op` g x) [a..b]) [(<), (>)] duplicate l x = elem x (delete x l) unique l x = notElem x (delete x l) maxOf f = maximum . (Nothing:) . map Just . concatMap (\l -> filter (f l) l) maxDuplicate = maxOf duplicate maxUnique = maxOf unique checkMatrixA k = all (any (\x -> mod x k == 0)) checkMatrixB k = all (any (\x -> mod k x > 0)) longestPrefix cmp (h:t) = h : map snd (takeWhile (uncurry cmp) (zip (h:t) t)) longest order lp = maximumBy (comparing length) . order . map lp . init . tails longestAscending = longest id $ longestPrefix (<=) longestDescending = longest reverse $ longestPrefix (>=) testAll = and [ meetTwice id negate (-3) 1 == False, meetTwice id sqrt 0 5 == True, mixed id negate (-3) 1 == True, mixed sqrt exp 1 5 == False, maxDuplicate [[1,2,3,2],[-4,-4],[5]] == Just 2, maxDuplicate [[1,2,3],[-4,-5,-6],[]] == Nothing, maxUnique [[1,2,3,2],[5,5],[0]] == Just 3, maxUnique [[1,2,1,2],[5,5],[]] == Nothing, checkMatrixA 3 [[1,2,6],[3,8,9],[10,12,11]] == True, checkMatrixA 3 [[1,2,4],[3,8,9],[10,12,11]] == False, checkMatrixB 12 [[1,2,6],[3,8,9],[6,11,12]] == False, checkMatrixB 12 [[1,2,7],[3,8,9],[6,11,12]] == True, longestDescending [5,3,8,6,4,2,6,7,1] == [8,6,4,2], longestDescending [1..6] == [1], longestAscending [5,3,8,6,4,2,6,7,1] == [2,6,7], longestAscending [6,5..1] == [1] ]