aboutsummaryrefslogtreecommitdiff
path: root/Math/Combinatorics/YoungTableaux.hs
blob: 89644695c7b9ccb0b09bca185304aa128b409850 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
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