Search code examples
haskellrecursionpermutation

Verifying if there are three elements that are the same and two elements that are the same in a list


I am given a list of 5 elements drawn from the list [1..6] sorted in ascending order, and I have to develop two functions:

  • check if there are exactly 4 equal elements (e.g. 11112, 44445, 15555),
  • check if there are exactly 3 equal elements, and exactly 2 equal elements (e.g. 22244,11122)

I can assume functions like numberOfOccurrences, isPermutation, isSorted, maximum, and minimum.

numberOfOccurrences :: Eq a => a -> [a] -> Int
numberOfOccurrences _ [] = 0
numberOfOccurrences x (y:ys)
  | x == y    = 1 + numberOfOccurrences x ys
  | otherwise = numberOfOccurrences x ys

isPermutation :: Eq a => [a] -> [a] -> Bool
isPermutation [] [] = True
isPermutation xs [] = False
isPermutation xs (y:ys) | length xs /= length (y:ys) = False
                        | otherwise = isPermutation (delete y xs) ys

My solution for the second one is:

p :: [Int] -> Bool
p xs = 3 == maximum (map length (group xs))

However, I should use the function isPermutation, and numberOfOccurrences. Any hints about this problem ?

Thanks to Daniel Wagner for finding my error. This would be the solution to 2, I think.

p :: [Int] -> Bool
p xs = 3 == maximum ns && length ns == 2
    where 
        ns = (map length (group xs))

However, it is not the solution required.


Solution

  • Personally, I'd start with the super dumb thing.

    fourEqual [a, b, c, d, e] =
           (a == b && b == c && c == d && d /= e)
        || (a /= b && b == c && c == d && d == e)
    

    It's easy to write, it's easy to read, and it isn't particularly inefficient.

    A similar strategy works for the other one.