nobsun #4893(2007/12/20 01:32 GMT) [ Haskell ] Rating2/2=1.00
ああそうか. inversion を求めて,隣接するものを採用,残りを採用したもので変換, というのを繰り返せばいいのか.これで多分,横棒数,段数ともに最小になるはず? 印字系は手抜きです(縦棒10本まで対応).置換を与えると,阿弥陀籤を印字します. 実行結果 *Main> :main [3,5,2,4,0,1] 0 1 2 3 4 5 | |-| | |-| |-| |-| | | | |-| |-| | |-| |-| |-| | |-| |-| | 3 5 2 4 0 1 *Main> :main [5,4,3,2,1,0] 0 1 2 3 4 5 |-| |-| |-| | |-| |-| | |-| |-| |-| | |-| |-| | |-| |-| |-| | |-| |-| | 5 4 3 2 1 0
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
module Main (main) where import Data.List import System.Environment main :: IO () main = do { a:_ <- getArgs ; let { e = read a :: [Int] ; s = sort e ; caption = putStrLn . concat . intersperse " " . map show } ; caption s >> putStr (showAmida (length e - 1) (amida e)) >> caption e } amida :: [Int] -> [[(Int,Int)]] amida p = reverse $ fst $ head $ dropWhile (not . null . snd) $ iterate f ([],invs) where invs = inversions p f (acc,invs) = case select invs of (xs,ys) -> (xs:acc, foldr map ys (map exchange xs)) inversions :: [Int] -> [(Int,Int)] inversions [] = [] inversions (y:ys) = map (flip (,) y) (filter (y >) ys) ++ inversions ys select :: [(Int,Int)] -> ([(Int,Int)],[(Int,Int)]) select invs = case partition ((1==) . uncurry subtract) $ sort $ invs of ([] ,ys) -> ([],ys) (x:xs,ys) -> case partition (share x) (xs++ys) of (zs,ws) -> case select ws of (us,vs) -> (x:us,zs++vs) share :: (Int,Int) -> (Int,Int) -> Bool share (x,y) (p,q) = x == p || x == q || y == p || y == q exchange :: (Int,Int) -> (Int,Int) -> (Int,Int) exchange (x,y) pq@(p,q) | x == p = (y,q) | x == q = (p,y) | y == p = (x,q) | y == q = (p,x) | otherwise = pq showAmida :: Int -> [[(Int,Int)]] -> String showAmida n = unlines . map (showStep n) showStep :: Int -> [(Int,Int)] -> String showStep n xs = '|':step n 0 xs where step n m xs | n == m = "" | otherwise = case xs of [] -> nostep $ step n (m+1) xs (i,_):rs | m == i -> astep $ step n (m+1) rs | otherwise -> nostep $ step n (m+1) xs nostep = (' ':).('|':) astep = ('-':).('|':)
Rating2/2=1.00-0+
[ reply ]
nobsun
#4893()
[
Haskell
]
Rating2/2=1.00
Rating2/2=1.00-0+