アルファベットの繰り上がり #2
- ref:アルファベットの繰り上がり
Enum クラスのデータを定義するというネタで。これで任意区間を簡単に取得できる。
import Char alpha_succ :: String -> String alpha_succ [] = "A" alpha_succ ('Z':cs) = 'A' : alpha_succ cs alpha_succ (c:cs) = succ c : cs num2alpha :: Int -> String num2alpha = reverse . num2alpha' where num2alpha' n | n < 26 = [chr (ord 'A' + n `mod` 26)] | otherwise = let m = (n - 26) `div` 26 in chr (ord 'A' + n `mod` 26) : num2alpha' m alpha2num :: String -> Int alpha2num s = foldl1 (\x y -> x * 26 + 26 + y) $ map c2n s where c2n c = ord c - ord 'A' data AlphabetNumber = AlphabetNumber String instance Show (AlphabetNumber) where show (AlphabetNumber s) = s instance Enum (AlphabetNumber) where toEnum n = AlphabetNumber (num2alpha n) fromEnum (AlphabetNumber s) = alpha2num s succ (AlphabetNumber s) = AlphabetNumber ((reverse . alpha_succ . reverse) s) an :: String -> AlphabetNumber an s = AlphabetNumber s main = print . (take 100) $ [an "A" .. ]