Problem 17

If the numbers 1 to 5 are written out in words: one, two, three, four, five, then there are 3 + 3 + 5 + 4 + 4 = 19 letters used in total.

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.Array.IArray
digit1 ::Array Int String
digit1 = 
    listArray(0,20)["","one","two","three","four","five","six",
                    "seven","eight","nine","ten","eleven","twelve",
                   "thirteen","fourteen","fifteen","sixteen",
                    "seventeen","eighteen","nineteen","twenty"]
digit2 ::Array Int String
digit2 = listArray(0,9)["","ten","twenty","thirty","forty","fifty","sixty",
                        "seventy","eighty","ninety"]

numToWords n | n <21 =digit1!n
             | n < 100 = let (a,b) = divMod n 10
                         in digit2!a++" "++digit1!b
             | n < 1000 = let (a,b')= divMod n 100
                              (b,c) = divMod b' 10
                          in if b==0&&c==0 then digit1!a++" hundred"
                             else digit1!a++" hundred and "++numToWords b'

p017 = (+11) .sum $ map (length.filter(/=' ').numToWords) [1..999]