Skip to content

Instantly share code, notes, and snippets.

@chaoxu
Last active January 2, 2019 18:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chaoxu/a4a60408a069edf3889e8328e685f700 to your computer and use it in GitHub Desktop.
Save chaoxu/a4a60408a069edf3889e8328e685f700 to your computer and use it in GitHub Desktop.
import Control.Arrow (second)
import Data.List.Extra (sort, groupSortOn)
-- Assuming we sort through counting sort
-- Including the sort inside groupSortOn
-- Sorting of tuples is radix sort with base = max coordinate
-- type alias for readability
type Partition x = [[x]]
type EquivalenceClass x = [x]
type ID = Int -- Unique id for each input string
-- simple functions
map2 = map . map
idx = zip [0 ..] -- index a list
hasDuplicate = any ((> 1) . length) . groupSortOn id
------------
hammingDistance1 :: [String] -> Bool
hammingDistance1 input = or $ zipWith condition p s
where
p = equivalences input
s = tail $ reverse $ equivalences $ map reverse input
condition :: Partition ID -> Partition ID -> Bool
condition a b = hasDuplicate $ zip (h a) (h b)
where
h = map snd . sort . (uncurry (map . flip (,)) =<<) . idx
equivalences :: [String] -> [Partition ID]
equivalences = equivalences'. return . idx
equivalences' :: Partition (ID, String) -> [Partition ID]
equivalences' xs
| null t = [ys]
| otherwise = ys : equivalences' (concatMap nextLayer xs)
where
t = snd $ head $ head xs
ys = map2 fst xs
nextLayer :: EquivalenceClass (ID, String) -> [EquivalenceClass (ID, String)]
nextLayer = map2 (second tail) . groupSortOn (head . snd)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment