import Control. Applicative
import Control
. Monad . Memo
import Data. Function
import qualified Data. List as L
import qualified Data. Map as M
sp = '_'
alignColumn = L. transpose . startEvalMemo . f . L. transpose . addsp
where
ff xs
= xs
++ replicate
( maxlen
- length xs
) sp
f xss
= g
<$> mapM ( \
( ys:yss
) -> ( ys:
) <$> memo f yss
) [ insertSP xss is
| is
<- groupOfIndex
$ head xss
] g [ ] = [ ]
insertSP xss1 is = f xss1 pre
where
pre
= zipWith ( \k
_ -> if elem k is
then Nothing
else Just sp
) [ 0 .. ] ( head xss1
) f [ ] cs
| all ( == Nothing
) cs
= [ ] where
where
g x Nothing = ( x, Nothing)
g x ( Just c) = ( c, Just x)
groupOfIndex xs
= map ( spi
++ ) . M
. elems
. fst . foldl f
( M
. empty
, 0 ) $ xs
where
spi = L. findIndices ( == sp) xs
f ( acc, i) x
| x == sp = ( acc, i+ 1 )
| otherwise = ( M
. insertWith
( ++ ) x
[ i
] acc
, i
+ 1 )
main = do
run [ "1" , "1" ]
run [ "1" , "2" ]
run [ "12" , "21" ]
run [ "11" , "12" ]
run [ "113" , "114" ]
run [ "123" , "134" ]
run [ "1212" , "1322" , "1122" ]
run [ "123" , "113" , "1323" ]
run [ "1234" , "4321" , "1122" ]
run [ "12121313432121233" , "21322312443213443" ]
-- 121_21_31_34_3212123__3
-- _2132_2312_44321___3443
where
run xs = do
aW1wb3J0IENvbnRyb2wuQXBwbGljYXRpdmUKaW1wb3J0IENvbnRyb2wuTW9uYWQuTWVtbwppbXBvcnQgRGF0YS5GdW5jdGlvbgppbXBvcnQgcXVhbGlmaWVkIERhdGEuTGlzdCBhcyBMCmltcG9ydCBxdWFsaWZpZWQgRGF0YS5NYXAgIGFzIE0KCnNwIDo6IENoYXIKc3AgPSAnXycKCmFsaWduQ29sdW1uIDo6IFtTdHJpbmddIC0+IFtTdHJpbmddCmFsaWduQ29sdW1uID0gTC50cmFuc3Bvc2UgLiBzdGFydEV2YWxNZW1vIC4gZiAuIEwudHJhbnNwb3NlIC4gYWRkc3AKICAgIHdoZXJlCiAgICAgIGFkZHNwIHhzcyA9IG1hcCBmZiB4c3MKICAgICAgICAgIHdoZXJlIG1heGxlbiA9IGZvbGRyIChceCBhIC0+IGlmIGxlbmd0aCB4ID4gYSB0aGVuIGxlbmd0aCB4IGVsc2UgYSkgMCB4c3MKICAgICAgICAgICAgICAgIGZmIHhzID0geHMgKysgcmVwbGljYXRlIChtYXhsZW4gLSBsZW5ndGggeHMpIHNwCiAgICAgIGYgW10gPSByZXR1cm4gW10KICAgICAgZiB4c3MgPSBnIDwkPiBtYXBNIChcKHlzOnlzcykgLT4gKHlzOikgPCQ+IG1lbW8gZiB5c3MpCiAgICAgICAgICAgICAgW2luc2VydFNQIHhzcyBpcyB8IGlzIDwtIGdyb3VwT2ZJbmRleCAkIGhlYWQgeHNzXQogICAgICBnIFtdID0gW10KICAgICAgZyB4cyA9IEwubWluaW11bUJ5IChjb21wYXJlIGBvbmAgbGVuZ3RoKSB4cwoKaW5zZXJ0U1AgOjogW1N0cmluZ10gLT4gW0ludF0gLT4gW1N0cmluZ10KaW5zZXJ0U1AgeHNzMSBpcyA9IGYgeHNzMSBwcmUKICAgIHdoZXJlCiAgICAgIHByZSA9IHppcFdpdGggKFxrIF8gLT4gaWYgZWxlbSBrIGlzIHRoZW4gTm90aGluZyBlbHNlIEp1c3Qgc3ApIFswLi5dIChoZWFkIHhzczEpCiAgICAgIGYgW10gY3MKICAgICAgICAgIHwgYWxsICg9PSBOb3RoaW5nKSBjcyA9IFtdCiAgICAgICAgICB8IG90aGVyd2lzZSA9IGZvbGRyIChceCBhY2MgLT4gbWF5YmUgc3AgaWQgeCA6IGFjYykgW10gY3MgOiBbXQogICAgICBmICh4czp4c3MpIGNzID0gKG1hcCBmc3QgeXMpIDogZiB4c3MgKG1hcCBzbmQgeXMpCiAgICAgICAgICB3aGVyZQogICAgICAgICAgICB5cyA9IHppcFdpdGggZyB4cyBjcwogICAgICAgICAgICAgICAgd2hlcmUKICAgICAgICAgICAgICAgICAgZyB4IE5vdGhpbmcgPSAoeCwgTm90aGluZykKICAgICAgICAgICAgICAgICAgZyB4IChKdXN0IGMpID0gKGMsIEp1c3QgeCkKCmdyb3VwT2ZJbmRleCA6OiBTdHJpbmcgLT4gW1tJbnRdXQpncm91cE9mSW5kZXggeHMgPSBtYXAgKHNwaSsrKSAuIE0uZWxlbXMgLiBmc3QgLiBmb2xkbCBmIChNLmVtcHR5LCAwKSAkIHhzCiAgICB3aGVyZQogICAgICBzcGkgPSBMLmZpbmRJbmRpY2VzICg9PXNwKSB4cwogICAgICBmIChhY2MsaSkgeAogICAgICAgICAgfCB4ID09IHNwID0gKGFjYywgaSsxKQogICAgICAgICAgfCBvdGhlcndpc2UgPSAoTS5pbnNlcnRXaXRoICgrKykgeCBbaV0gYWNjLCBpKzEpCgptYWluIDo6IElPICgpCm1haW4gPSBkbwogICAgcnVuIFsiMSIsIjEiXQogICAgcnVuIFsiMSIsIjIiXQogICAgcnVuIFsiMTIiLCAiMjEiXQogICAgcnVuIFsiMTEiLCAiMTIiXQogICAgcnVuIFsiMTEzIiwgIjExNCJdCiAgICBydW4gWyIxMjMiLCAiMTM0Il0KICAgIHJ1biBbIjEyMTIiLCAiMTMyMiIsICIxMTIyIl0KICAgIHJ1biBbIjEyMyIsICIxMTMiLCAiMTMyMyJdCiAgICBydW4gWyIxMjM0IiwgIjQzMjEiLCAiMTEyMiJdCiAgICBydW4gWyIxMjEyMTMxMzQzMjEyMTIzMyIsICIyMTMyMjMxMjQ0MzIxMzQ0MyJdCiAgICAtLSAxMjFfMjFfMzFfMzRfMzIxMjEyM19fMwogICAgLS0gXzIxMzJfMjMxMl80NDMyMV9fXzM0NDMKICAgIHdoZXJlCiAgICAgIHJ1biB4cyA9IGRvCiAgICAgICAgICBtYXBNXyBwdXRTdHJMbiB4cwogICAgICAgICAgcHV0U3RyTG4gLiB1bmxpbmVzICQgYWxpZ25Db2x1bW4geHMK