2013年10月17日木曜日

開発環境

『初めてのプログラミング 第2版』(Chris Pine 著、長尾 高弘 訳、オライリー・ジャパン、2010年、ISBN978-4-87311-469-9)の10章(章全部で復習), 10.5(練習問題続き)、拡張 english_numberをHaskellで解いてみる。

その他参考書籍

拡張 english umber

コード(BBEdit)

sample.hs

{-# OPTIONS -Wall -Werror #-}

main :: IO ()
main = do
    line <- getLine
    if line == ""
    then return ()
    else do
        let n = read line :: Integer
        putStrLn $ englishNumber n
        main


englishNumber :: Integer -> String
englishNumber a
    | a < 0 = "自然数(0から)を指定してください"
    | a == 0 = "zero"
    | a < 100 =
        let ones_place = ["one", "two", "three", "four", "five",
                          "six", "seven", "eight", "nine"]
            tens_place = ["ten", "twenty", "thirty", "forty", "fifty",
                          "sixty", "seventy", "eighty", "ninety"]
            teenagers = ["eleven", "twelve", "thirteen", "fourteen", "fifteen", 
                         "sixteen", "seventeen", "eighteen", "nineteen"]
            b = div a 10
            c = a - 10 * b
            inner :: Integer -> Integer -> String
            inner 0 0 = ""
            inner d 0 = index (d - 1) tens_place
            inner 0 d = index (d - 1) ones_place
            inner 1 d = index (d - 1) teenagers
            inner d e = index (d - 1) tens_place ++ 
                        '-':(index (e - 1) ones_place)
        in inner b c
    | otherwise =
        let others :: [(Integer, String)]
            others = [(2, "hundred"),
                      (3, "thousand"),
                      (6, "million"),
                      (9, "billion"),
                      (12, "trillion"),
                      (15, "quandrillion"),
                      (18, "quintillion"),
                      (21, "sextillion"),
                      (24, "septillion")]
            
            inner :: Integer -> [(Integer, String)] -> String
            inner b [] = englishNumber b
            inner b c =
                let d = last c
                    e = init c
                    f = fst d
                    g = snd d
                    h = 10 ^ f
                    i = div b h
                    j = b - h * i
                    inner1 :: Integer -> Integer -> String
                    inner1 0 _ = ""
                    inner1 k 0 = englishNumber k ++ ' ':g
                    inner1 k _ = englishNumber k ++ ' ':g ++ " "
                in (inner1 i j) ++ (inner j e)
        in inner a others

index :: Integer -> [a] -> a
index n (x:xs)
    | n == 0 = x
    | otherwise = index (n - 1) xs
index _ [] = error "空っぽ" 

入出力結果(Terminal, runghc)

$ runghc sample.hs
1
one
5
five
10
ten
15
fifteen
25
twenty-five
12345
twelve thousand three hundred forty-five
1234567890123456789012345
one septillion two hundred thirty-four sextillion five hundred sixty-seven quintillion eight hundred ninety quandrillion one hundred twenty-three trillion four hundred fifty-six billion seven hundred eighty-nine million twelve thousand three hundred forty-five

$

0 コメント:

コメントを投稿