Excel列名変換問題やってみた。
Excel列名変換問題で第2回社内プログラミングコンテストを開催してみた(前編) - give IT a try
最初にperlでやってみてから、haskellでもだいたいおんなじ感じで書いてみた。
haskellの方は出入力とかよくわかんない。
use strict; use warnings; use utf8; sub col_conv { my $str = shift; my $n = shift; if(length($str) == 0) { return $n; } $n *= 26; $n += ord($str) - ord('A') + 1; return col_conv( substr($str, 1), $n ); } sub conv_col { my $str = shift; my $n = shift; # my $rem = $n % 26; my $rem = ($n + 25) % 26; # my $left = ($n - $rem) / 26; my $left = ($n - $rem - 1) / 26; if($n == 0) { return $str; } else { return conv_col( chr($rem - 1 + ord('A')) . $str, $left ); } } my $type = $ARGV[0]; my $input = $ARGV[1]; if($type == 0) { print col_conv($input, 0), "\n"; } else { print conv_col("", $input), "\n"; }
import Data.Char import System colConv' :: String -> Int -> Int colConv' [] n = n colConv' (x:xs) n = colConv' xs n' where n' = n * 26 + ord(x) - ord('A') + 1 colConv strs = colConv' strs 0 convCol' :: String -> Int -> String convCol' strs 0 = strs convCol' strs n = convCol' (s : strs) left where an = ord('A') -- rem = n `mod` 26 rem = (n + 25) `mod` 26 s = chr(rem - 1 + an) -- left = (n - rem) `div` 26 left = (n - rem - 1) `div` 26 convCol = convCol' "" main = do args <- getArgs let [cvtype, input] = args if (read cvtype::Int) == 0 then putStrLn $ show $ colConv input else putStrLn $ convCol $ (read input::Int)
[追記]convColの方でバグがあったので修正[/追記]