Home > Software engineering >  Return a list, which contains a pair of elements, but only if the respective elements' sums are
Return a list, which contains a pair of elements, but only if the respective elements' sums are

Time:10-23

Implement the oddPairs :: [Int] -> [Int] -> [(Int, Int)] function that returns a list of pairs, but only if the parameters' lists' respective elements' sums are odd.

For example:

oddPairs [1,2,3] [2,2,2] == [(1,2),(3,2)]

oddPairs [1,3,5] [2,4,6] == zip [1,3,5] [2,4,6]

oddPairs [1,2,3] [1,2,3] == []

So far, I've tried

oddPairs (x:xs) (y:ys) | (x y) `mod` 2 == 0 = []
                       | (x y) `mod` 2 /= 0 = [(x, y)]    oddPairs (xs) (ys)

And on the first example, it returns only [(1,2)], on the second, it returns the correct values but with a Non-exhaustive patterns error.

CodePudding user response:

In case the two items are even, you should not just return an empty list, but continue the recursion until at least one of the lists is exhausted, so:

oddPairs :: Integral a => [a] -> [a] -> [(a, a)]
oddPairs [] _ = []
oddPairs _ [] = []
oddPairs (x:xs) (y:ys)
    -- keep searching for new items ↓
    | (x y) `mod` 2 == 0 = oddPairs xs ys
    | otherwise = (x, y) : oddPairs xs ys

CodePudding user response:

Another way to look at the problem is that you want only the pairs that have an odd sum. This is a slight difference in emphasis that might lead to the following.

Use the zip function to combine each list into pairs. Then use filter to find the ones with odd sum.

oddPairs :: Integral a => [a] -> [a] -> [(a, a)]
oddPairs f s = filter oddPair (zip f s)
    where oddPair (l, r) = not $ even (l   r)
  • Related