34 lines
1.5 KiB
Haskell
34 lines
1.5 KiB
Haskell
-- If all the numbers from 1 to 1000 (one thousand) inclusive were written
|
|
-- out in words, how many letters would be used?
|
|
--
|
|
-- NOTE: Do not count spaces or hyphens. For example, 342 (three hundred and
|
|
-- forty-two) contains 23 letters and 115 (one hundred and fifteen) contains
|
|
-- 20 letters. The use of "and" when writing out numbers is in compliance
|
|
-- with British usage.
|
|
|
|
import Data.Char
|
|
import Data.List
|
|
|
|
inWords :: Integer -> String
|
|
inWords n
|
|
| n < 0 = "negative " ++ inWords (negate n)
|
|
| n <= 19 = [ "zero", "one", "two", "three", "four", "five", "six"
|
|
, "seven", "eight", "nine", "ten", "eleven", "twelve"
|
|
, "thirteen", "fourteen", "fifteen", "sixteen"
|
|
, "seventeen", "eighteen", "nineteen"
|
|
] !! fromInteger n
|
|
| n <= 99 = case n `divMod` 10 of
|
|
(m, q) -> let tens = [ "twenty", "thirty", "forty", "fifty"
|
|
, "sixty", "seventy", "eighty", "ninety" ]
|
|
in (tens !! fromInteger (m - 2)) ++
|
|
(if q == 0 then "" else ("-" ++ inWords q))
|
|
| n <= 999 = case n `divMod` 100 of
|
|
(m, 0) -> inWords m ++ " hundred"
|
|
(m, r) -> inWords m ++ " hundred and " ++ inWords r
|
|
| n <= 9999 = case n `divMod` 1000 of
|
|
(m, 0) -> inWords m ++ " thousand"
|
|
(m, r) | r <= 99 -> inWords m ++ " thousand and " ++ inWords r
|
|
| otherwise -> inWords m ++ " thousand " ++ inWords r
|
|
|
|
main = print $ length $ filter isAlpha $ concatMap inWords [1..1000]
|