succ でいいじゃん,と思ったらダメだった。
Prelude> succ 'A' 'B' Prelude> succ 'Z' '['
Ruby の String#succ はうまくやってくれるのに。
なら,26進数だと考えて素直に繰り上がりを処理すればいいか……と思ったけどこれもダメ。'A' は 0 じゃない。要するに 0 が無いんだな。結局繰り上がりのところで汚いコードになってしまった。
module Main ( main ) where import Data.Char ( ord, chr ) import Data.List ( mapAccumR, intersperse ) succS :: [Char] -> Int -> [Char] succS s n = map intToAlpha $ g $ mapAccumR f n $ map alphaToInt s where alphaToInt c = (ord c ) - 64 intToAlpha i = chr (i + 64) f acc x = let (d,m) = (acc+x) `divMod` 26 in if m == 0 then (d-1,26) else (d,m) g (0,b) = b g (a,b) = a:b main :: IO () main = putStr $ concat $ intersperse "," $ take 100 $ iterate (flip succS 1) "A"
実行:
^o^ >runhaskell succS.hs A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,AA,AB,AC,AD,AE,AF,AG,AH,AI,A J,AK,AL,AM,AN,AO,AP,AQ,AR,AS,AT,AU,AV,AW,AX,AY,AZ,BA,BB,BC,BD,BE,BF,BG,BH,BI,BJ, BK,BL,BM,BN,BO,BP,BQ,BR,BS,BT,BU,BV,BW,BX,BY,BZ,CA,CB,CC,CD,CE,CF,CG,CH,CI,CJ,CK ,CL,CM,CN,CO,CP,CQ,CR,CS,CT,CU,CV