Home > Enterprise >  Decide if a list has an even number of elements without counting the number of elements
Decide if a list has an even number of elements without counting the number of elements

Time:10-18

Implement the isLengthEven :: [a] -> Bool function that decides if a list contains an even number of elements. In this exercise, using the length function or any other function that returns the number of elements of a list is prohibited. Hint: All we have to check is whether we can walk the entirety of the list through two by two or does the function miss an item at the very end.

For example: isLengthEven "Apple" == True, isLengthEven "Even" == True, isLengthEven [] == False

So far, I tried pattern matching and recursion, which is in my opinion the optimal way of doing this exercise. My code is as follows:

isLengthEven :: [a] -> Bool
isLengthEven [] = False
isLengthEven (x:[]) = False
isLengthEven (x:(y:[])) = True
isLengthEven (x:(y:(z:[]))) = False
isLengthEven (x:(y:(z:(q:[])))) = True
isLengthEven (x:xs) = isLengthEven (xs)

This returns the correct values up until I insert the fifth element into the list. It returns True for any number of elements above or equal to 5. I suppose there's a problem with the recursion part.

CodePudding user response:

You need only two base cases here:

  1. an empty list, which has as length 0 and thus should return True; and
  2. a singleton list which contains one element and thus has an odd length.

The recursive cases each time move two steps forward in the list, so:

isLengthEven :: [a] -> Bool
isLengthEven [] = True
isLengthEven [x] = False
isLengthEven (_:_:xs) = isLengthEven xs

Often one defines two functions: isLengthEven and isLengthOdd and thus these functions each time call each other recursively with:

isLengthEven :: [a] -> Bool
isLengthEven [] = True
isLengthEven (_:xs) = isLengthOdd xs

isLengthOdd :: [a] -> Bool
isLengthOdd [] = False
isLengthOdd (_:xs) = isLengthEven xs
  • Related