type Tableau a = [[a]] --data SSYT a = S [[a]] type SSYT a = [[a]] type GT a = [[a]] --instance Show a => Show (SSYT a) --where show (S xs) = show $ fst $ break null xs rowInsert :: Ord a => SSYT a -> a -> SSYT a rowInsert t = truncInfList . rowInsert' (t ++ (repeat [])) rowInsert' :: Ord a => SSYT a -> a -> SSYT a rowInsert' t x = case break (>x) (head t) of (r, []) -> (r ++ [x]):(tail t) (r1, r2) -> (r1 ++ x:(tail r2)):(rowInsert' (tail t) (head r2)) robinsonSchensted :: Ord a => [a] -> SSYT a robinsonSchensted = truncInfList . foldl rowInsert' (repeat []) truncInfList :: [[a]] -> [[a]] truncInfList = fst . break null toRowWord :: Ord a => SSYT a -> [a] toRowWord = concat . reverse {-- rowInsert :: Ord a => SSYT a -> a -> SSYT a rowInsert (S t) x = case break (>x) (head t) of (r, []) -> S $ (r ++ [x]):(tail t) (r1, r2) -> let S s = rowInsert (S (tail t)) (head r2) in S $ (r1 ++ x:(tail r2)):s --} isRowWord' :: Ord a => [a] -> [a] -> [a] -> Bool isRowWord' _ ys [] = ys == [] isRowWord' [] [] zs = isRowWord' [head zs] [] (tail zs) isRowWord' xs [] zs = if last xs <= head zs then isRowWord' (xs ++ [head zs]) [] (tail zs) else isRowWord' [] xs zs isRowWord' xs ys zs = if xs == [] || last xs <= head zs then head ys > head zs && (isRowWord' (xs ++ [head zs]) (tail ys) (tail zs)) else ys == [] && isRowWord' [] xs zs isRowWord :: Ord a => [a] -> Bool isRowWord = isRowWord' [] [] reduceWord :: Ord a => [a] -> [a] reduceWord xs | length xs <= 2 = xs | otherwise = let ys = reduceWord $ init xs in reduceWord' (init $ init ys) (last $ init ys, last ys, last xs) [] {-- | otherwise = let ys = reduceWord $ init xs in let (zs, ws) = splitAt (length ys - 2) ys in reduceWord'' zs (ws ++ [last xs]) --} reduceWord' :: Ord a => [a] -> (a, a, a) -> [a] -> [a] reduceWord' [] (u, v, w) ys = if isRowWord (u:v:w:ys) then u:v:w:ys else if w < v && u <= v then if u > w then u:w:v:ys else v:u:w:ys else u:v:w:ys reduceWord' xs (u, v, w) ys = if isRowWord $ xs ++ (u:v:w:ys) then xs ++ (u:v:w:ys) else if w < v && u <= v then if u > w then reduceWord' (init xs) (last xs, u, w) (v:ys) else reduceWord' (init xs) (last xs, v, u) (w:ys) else reduceWord' (init xs) (last xs, u, v) (w:ys) prop_ReduceWord :: [Int] -> Bool prop_ReduceWord = isRowWord . reduceWord prop_ReduceWord' :: [Int] -> Bool prop_ReduceWord' xs = (length xs) == (length $ reduceWord xs) prop_ReduceWord_RobinsonSchensted :: [Int] -> Bool prop_ReduceWord_RobinsonSchensted xs = (toRowWord $ robinsonSchensted xs) == (reduceWord xs) reduceWord'' :: Ord a => [a] -> [a] -> [a] reduceWord'' [] (u:v:w:ys) = if isRowWord (u:v:w:ys) then u:v:w:ys else if w < v && u <= v then if u > w then u:w:v:ys else v:u:w:ys else u:v:w:ys reduceWord'' xs (u:v:w:ys) = if isRowWord $ xs ++ (u:v:w:ys) then xs ++ (u:v:w:ys) else if w < v && u <= v then if u > w then reduceWord'' (init xs) (last xs:u:w:v:ys) else reduceWord'' (init xs) (last xs:v:u:w:ys) else reduceWord'' (init xs) (last xs:u:v:w:ys) reduceWord'' xs ys = xs ++ ys