Excel 列名変換問題


息抜きに 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"