How can the solution, presented below, to the following problem be improved? Can it be more efficient in time and space? Is there a space leak?
Problem:
Given an input list of Astronauts
, produce a list of pairs of Astronauts
such that the pairs do not have two Astronauts
from the same country. Assume the input has a list of Astronauts
with unique identifier
s.
data Astronaut = Astronaut { identifier :: Int, country :: String } deriving (Eq)
astronautPairs :: [Astronaut] -> [(Astronaut, Astronaut)]
astronautPairs xs = foldl accumulatePairs [] [(a, b) | a <- xs, b <- xs, country a /= country b]
where
accumulatePairs pairs pair = if hasPair pair pairs then pairs else pair:pairs
hasPair pair@(a,b) ((c,d):xs) = a == d && b == c || hasPair pair xs
hasPair _ [] = False