息抜きに Excel の列名変換問題というのを Haskell でやってみました。 Excel の列名が何列目であるか,逆に数値を列名に変換せよという問題です。
import System
i2c i = i2c' i 'A'
where i2c' i' c = if i' == 1 then c else i2c' (pred i') (succ c)
c2i c = c2i' c 1
where c2i' c' i = if c' == 'A' then i else c2i' (pred c') (succ i)
col2num col = foldl (\n c -> 26 * n + (c2i c)) 0 col
num2col num =
let
(q, r) = divMod num 26
in
case (q, r) of
(1, 0) -> "Z"
(0, _) -> [i2c r]
(_, 0) -> num2col q ++ "Z"
_ -> num2col q ++ [i2c r]
main = do (x:xs) <- getArgs
case read x of
0 -> mapM_ (print . col2num) xs
1 -> mapM_ (print . num2col . read) xs
[2011-11-03 17:40 更新] num2col
において 26 で割った余りが 0 であるとき ('Z' になるとき) を処理していなかったのを修正。
[2011-11-14 05:15 更新] 上の修正で誤ったままだったので修正。ちゃんとテストしてなくてすみません。
問題に異常な引数は考慮しなくて良いとあったので,考慮していません。
> .\excel.exe 0 A AA XFD 1 27 16384 > .\excel.exe 1 1 27 16384 "A" "AA" "XFD"