import Data.Maybe digits = [(0, "") ,(1, "one") ,(2, "two") ,(3, "three") ,(4, "four") ,(5, "five") ,(6, "six") ,(7, "seven") ,(8, "eight") ,(9, "nine") ,(10, "ten") ,(11, "eleven") ,(12, "twelve") ,(13, "thirteen") ,(14, "fourteen") ,(15, "fifteen") ,(16, "sixteen") ,(17, "seventeen") ,(18, "eighteen") ,(19, "nineteen")] tenDigits = [(2, "twenty") ,(3, "thirty") ,(4, "forty") ,(5, "fifty") ,(6, "sixty") ,(7, "seventy") ,(8, "eighty") ,(9, "ninety")] numsTemplate k d = fromJust \$ lookup k d tens = flip numsTemplate tenDigits units = flip numsTemplate digits hundreds = (++ " hundred") . units buildNumberString :: Int -> String buildNumberString x | x < 20 = units x | x < 100 = build99 x | otherwise = build999 x build99 x = build' \$ numberToDigits x where build' [t, u] | u == 0 = tens t | otherwise = tens t ++ "-" ++ units u build999 x = build' \$ numberToDigits x where build' [h, t, u] | num99 == 0 = (hundreds h) | otherwise = (hundreds h) ++ " and " ++ buildNumberString num99 where num99 = to99 t u to99 x y = x * 10 + y numberToDigits :: Int -> [Int] numberToDigits x = map (read . singleton) \$ show x singleton x = [x] numStrings = (map buildNumberString [1..999]) ++ ["one thousand"] answer = length \$ concat \$ map (filter (flip notElem "- ")) \$ numStrings