Life Goes On

まあまあだけど楽しんでる方です

17問目

http://projecteuler.net/index.php?section=problems&id=17
せっかくなので、さらにもう1問。
1から1000までの数を英語で表記して、その文字数を足し合わせる。

main = print $ euler017 1000

euler017 :: Int -> Int
euler017 n =  sum $ map (length . wordsXXXX) [1..n]

wordsXXXX :: Int -> String
wordsXXXX n
  | (n == 1000) = "one" ++ "thousand"
  | (n < 100) = wordsXX n
  | (mod n 100 == 0) = word (div n 100) ++ "hundred"
  | otherwise = word (div n 100) ++ "hundred"
    ++ "and" ++ wordsXX (mod n 100)

wordsXX :: Int -> String
wordsXX n
  | (n < 20) = word n
  | otherwise = word (n - (mod n 10)) ++ word (mod n 10)

word :: Int -> String
word 0 = ""
word 1 = "one"
word 2 = "two"
word 3 = "three"
word 4 = "four"
word 5 = "five"
word 6 = "six"
word 7 = "seven"
word 8 = "eight"
word 9 = "nine"
word 10 = "ten"
word 11 = "eleven"
word 12 = "twelve"
word 13 = "thirteen"
word 14 = "fourteen"
word 15 = "fifteen"
word 16 = "sixteen"
word 17 = "seventeen"
word 18 = "eighteen"
word 19 = "nineteen"
word 20 = "twenty"
word 30 = "thirty"
word 40 = "forty"
word 50 = "fifty"
word 60 = "sixty"
word 70 = "seventy"
word 80 = "eighty"
word 90 = "ninety"