Group Anagrams


In [1]:
import Data.List

In [2]:
groupAnagrams :: [String] -> [String]
groupAnagrams xs =
    sortOn sort xs

In [3]:
groupAnagrams ["hot", "god", "tea", "dog", "eat"]


["tea","eat","god","dog","hot"]

In [4]:
import Test.QuickCheck

In [5]:
import Data.Function (on)

In [6]:
import Control.Monad (join)
import Control.Arrow --(***)

In [7]:
testAnagrams :: [String] -> Bool
testAnagrams xs =
    let
        anagramCompare = (==) `on` sort
        groups = groupBy anagramCompare $ groupAnagrams xs
    in
        anagramCompare (concat groups) xs &&
        let
            heads = map (sort . head) groups
        in
            uncurry (==) $ mapPair length (nub heads, heads)
    where
        mapPair = join (***)

In [8]:
quickCheck testAnagrams


+++ OK, passed 100 tests.