開発環境
- OS X Lion - Apple(OS)
- Emacs、BBEdit - Bare Bones Software, Inc. (Text Editor)
- Haskell (純粋関数型プログラミング言語)
- GHC (The Glasgow Haskell Compiler) (処理系)
『初めてのプログラミング 第2版』(Chris Pine 著、長尾 高弘 訳、オライリー・ジャパン、2010年、ISBN978-4-87311-469-9)の10章(章全部で復習), 10.5(練習問題続き)、「壁にビールが99本」をHaskellで解いてみる。
その他参考書籍
- プログラミングHaskell (オーム社) Graham Hutton(著) 山本 和彦(翻訳)
- Real World Haskell―実戦で学ぶ関数型言語プログラミング (オライリージャパン) Bryan O'Sullivan John Goerzen Don Stewart(著) 山下 伸夫 伊東 勝利 株式会社タイムインターメディア(翻訳)
「壁にビールが99本」
コード(BBEdit)
sample.hs
{-# OPTIONS -Wall -Werror #-}
import qualified Data.Char as Char
main :: IO ()
main = do
let englishNumbers = map (\x -> (englishNumber x, englishNumber (x - 1)))
[9999, 9998.. 9990]
[a, b] = map englishNumber [2,1]
mapM_ (\(c, d) -> do
putStrLn $ capitalize c ++ " bottles of beer on the wall, " ++
c ++ " bottles of beer!"
putStrLn $ "Take one down, pass it around, " ++
d ++ " bottles of beer on the wall!")
englishNumbers
putStrLn $ replicate 100 '*'
putStrLn $ capitalize a ++ " bottles of beer on the wall, " ++
a ++ " bottles of beer!"
putStrLn $ "Take one down, pass it around, " ++
b ++ " bottle of beer on the wall!"
putStrLn $ capitalize b ++ " bottle of beer on the wall, " ++ b ++ " bottle of beer!"
putStrLn "Take one down, pass it around, no more bottles of beer on the wall!"
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 "空っぽ"
capitalize :: String -> String
capitalize [] = []
capitalize (x:xs) = Char.toUpper x:xs
入出力結果(Terminal, runghc)
$ runghc sample.hs Nine thousand nine hundred ninety-nine bottles of beer on the wall, nine thousand nine hundred ninety-nine bottles of beer! Take one down, pass it around, nine thousand nine hundred ninety-eight bottles of beer on the wall! Nine thousand nine hundred ninety-eight bottles of beer on the wall, nine thousand nine hundred ninety-eight bottles of beer! Take one down, pass it around, nine thousand nine hundred ninety-seven bottles of beer on the wall! Nine thousand nine hundred ninety-seven bottles of beer on the wall, nine thousand nine hundred ninety-seven bottles of beer! Take one down, pass it around, nine thousand nine hundred ninety-six bottles of beer on the wall! Nine thousand nine hundred ninety-six bottles of beer on the wall, nine thousand nine hundred ninety-six bottles of beer! Take one down, pass it around, nine thousand nine hundred ninety-five bottles of beer on the wall! Nine thousand nine hundred ninety-five bottles of beer on the wall, nine thousand nine hundred ninety-five bottles of beer! Take one down, pass it around, nine thousand nine hundred ninety-four bottles of beer on the wall! Nine thousand nine hundred ninety-four bottles of beer on the wall, nine thousand nine hundred ninety-four bottles of beer! Take one down, pass it around, nine thousand nine hundred ninety-three bottles of beer on the wall! Nine thousand nine hundred ninety-three bottles of beer on the wall, nine thousand nine hundred ninety-three bottles of beer! Take one down, pass it around, nine thousand nine hundred ninety-two bottles of beer on the wall! Nine thousand nine hundred ninety-two bottles of beer on the wall, nine thousand nine hundred ninety-two bottles of beer! Take one down, pass it around, nine thousand nine hundred ninety-one bottles of beer on the wall! Nine thousand nine hundred ninety-one bottles of beer on the wall, nine thousand nine hundred ninety-one bottles of beer! Take one down, pass it around, nine thousand nine hundred ninety bottles of beer on the wall! Nine thousand nine hundred ninety bottles of beer on the wall, nine thousand nine hundred ninety bottles of beer! Take one down, pass it around, nine thousand nine hundred eighty-nine bottles of beer on the wall! **************************************************************************************************** Two bottles of beer on the wall, two bottles of beer! Take one down, pass it around, one bottle of beer on the wall! One bottle of beer on the wall, one bottle of beer! Take one down, pass it around, no more bottles of beer on the wall! $
0 コメント:
コメントを投稿