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.
In [138]:
let units = [
""
"one"
"two"
"three"
"four"
"five"
"six"
"seven"
"eight"
"nine"
]
let teens = [
"ten"
"eleven"
"twelve"
"thirteen"
"fourteen"
"fifteen"
"sixteen"
"seventeen"
"eighteen"
"nineteen"
]
let tens = [
""
"ten" // handled in "teens" case, probably not needed?
"twenty"
"thirty"
"forty"
"fifty"
"sixty"
"seventy"
"eighty"
"ninety"
]
let hundred = "hundred"
let thousand = "thousand"
let breakNumberIntoPowerParts n =
let numberByPowerPosition =
n.ToString().ToCharArray()
|> Array.map (fun x -> int(string(x)))
|> Array.rev
seq {
for i = 0 to numberByPowerPosition.Length - 1 do
yield (i, (numberByPowerPosition.[i]))
}
|> Seq.toList
|> List.rev
let simpleStringify pow10 n =
match pow10 with
| 3 -> units.[n] + thousand
| 2 -> if n > 0 then units.[n] + hundred else ""
| 1 -> tens.[n]
| 0 -> units.[n]
| _ -> ""
let rec stringifyPowerParts (digitPairs:(int * int) list) =
if digitPairs.IsEmpty then [] else
let (pow10, n) = List.head digitPairs
if pow10 = 1 && n = 1 then [teens.[snd(List.head(List.tail digitPairs))]; ""]
else [(simpleStringify pow10 n)] @ (stringifyPowerParts (List.tail digitPairs))
let maybeInsertAnd (numList:string list) =
if numList.Length < 3 then numList // no "and" needed, number < 100
else
let revNumList = List.rev numList
let unitAndTen = revNumList.[0..1]
let allTheRest = revNumList.[2..(revNumList.Length-1)]
if revNumList.[0] <> "" || revNumList.[1] <> "" then
(unitAndTen @ ["and"] @ allTheRest)
|> List.rev
else numList
let countEnglishLongForm n =
breakNumberIntoPowerParts n
|> stringifyPowerParts
|> maybeInsertAnd
|> List.filter (fun s -> s <> "")
|> String.concat ""
|> String.length
[1..1000]
|> List.map countEnglishLongForm
|> List.sum
Out[138]:
In [ ]: