Skip to content

Instantly share code, notes, and snippets.

@DirkyJerky
Last active February 22, 2016 19:31
Show Gist options
  • Save DirkyJerky/ba6869297330400af5cb to your computer and use it in GitHub Desktop.
Save DirkyJerky/ba6869297330400af5cb to your computer and use it in GitHub Desktop.
Personal Haskell library for Lexographic Permutations
module Data.List.Lexos (lexoPermutation, lexoList) where
getKHelper :: Ord a => [a] -> Int -> Maybe Int -> Maybe Int
getKHelper (x:y:ys) currIndex maybeIndex = if (x < y) then getKHelper (y:ys) (currIndex + 1) (Just currIndex) else getKHelper (y:ys) (currIndex + 1) maybeIndex
getKHelper _ _ maybeIndex = maybeIndex
getK :: Ord a => [a] -> Maybe Int
getK xs = getKHelper xs 0 Nothing
getLHelper :: Ord a => [a] -> a -> Int -> Int -> Int
getLHelper (x:xs) workingValue index resIndex = if (x > workingValue) then (getLHelper xs workingValue (index + 1) index) else (getLHelper xs workingValue (index + 1) resIndex)
getLHelper _ _ _ resIndex = resIndex
getL k xs = getLHelper xs (xs !! k) 0 0
swap :: Int -> Int -> [a] -> [a]
swap x y xs = let (l1, e1:ys) = splitAt x xs; (l2, e2:l3) = splitAt (y - x - 1) ys in (l1 ++ [e2] ++ l2 ++ [e1] ++ l3)
reverseSeqToEnd i xs = let (front, back) = splitAt i xs in front ++ reverse back
lexoPermutation :: Ord a => [a] -> Maybe [a]
lexoPermutation xs = do
k <- getK xs
let l = getL k xs
let swapped = swap k l xs
let reversed = reverseSeqToEnd (k+1) swapped
return reversed
lexoList :: Ord a => [a] -> [[a]]
lexoList xs = maybe [xs] ((xs :) . lexoList) (lexoPermutation xs) -- lexos array = array ++ ifthen lexographicPermutation xs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment