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.
def to_words(num)
a0 = %w{ one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen }
a1 = %w{ twenty thirty forty fifty sixty seventy eighty ninety }
case num
when 1..19
a0[num-1]
when 20..99
num % 10 != 0 ? "#{a1[(num-20)/10]}#{a0[num % 10 - 1]}" : a1[(num-20)/10]
when 100..999
num % 100 != 0 ? "#{to_words(num/100)}hundredand#{to_words(num % 100)}" : "#{to_words(num/100)}hundred"
when 1000
"onethousand"
end
end
puts (1..1000).inject('') { |acc,n| acc << to_words(n)}.size[/code]
def to_words(num):
a0 = 'one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen'.split(' ')
a1 = 'twenty thirty forty fifty sixty seventy eighty ninety'.split(' ')
if 1<= num <= 19: return a0[num-1]
if 20 <= num <= 99:
return "%s%s" % (a1[(num-20)/10], a0[num % 10 - 1]) if num % 10 != 0 else a1[(num-20)/10]
if 100 <= num <= 999:
return "%shundredand%s" % (to_words(num/100), to_words(num % 100)) \
if num % 100 != 0 else "%shundred" % to_words(num/100)
if num == 1000: return "onethousand"
print sum([len(to_words(n)) for n in range(1,1001)])
W sumie sprawdzanie zakresów nie jest potrzebne:
def to_words(num):
a0 = 'one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen'.split(' ')
a1 = 'twenty thirty forty fifty sixty seventy eighty ninety'.split(' ')
if num <= 19: return a0[num-1]
if num <= 99: return "%s%s" % (a1[(num-20)/10], a0[num % 10 - 1]) if num % 10 != 0 else a1[(num-20)/10]
if num <= 999: return "%shundredand%s" % (to_words(num/100), to_words(num % 100)) if num % 100 != 0 else "%shundred" % to_words(num/100)
if num == 1000: return "onethousand"
def to_words(num: Int): String = {
val a0 = ("one two three four five six seven eight nine ten" +
"eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen")
.split(' ')
val a1 = "twenty thirty forty fifty sixty seventy eighty ninety".split(' ')
if (1 to 19 contains num) return a0(num-1)
if (20 to 99 contains num) return if (num % 10 != 0)
"%s%s".format(a1((num-20)/10), a0(num % 10 - 1))
else a1((num-20)/10)
if (100 to 999 contains num) return if (num % 100 != 0)
"%shundredand%s".format(to_words(num/100), to_words(num % 100))
else "%shundred".format(to_words(num/100))
if (num == 1000) "onethousand" else ""
}
println((for(n <- 1 to 1000) yield to_words(n).length).foldLeft(0)(_ + _))
Algorytm można trochę skrócić, bo zakresy nie są potrzebne. Np. można tą funkcję zapisać tak:
def to_words(num: Int): String = {
val a0 = "one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen".split(' ')
val a1 = "twenty thirty forty fifty sixty seventy eighty ninety".split(' ')
if (num <= 19) return a0(num-1)
if (num <= 99) return if (num % 10 != 0) "%s%s".format(a1((num-20)/10), a0(num % 10 - 1)) else a1((num-20)/10)
if (num <= 999) return if (num % 100 != 0) "%shundredand%s".format(to_words(num/100), to_words(num % 100)) else "%shundred".format(to_words(num/100))
if (num == 1000) "onethousand" else ""
}
A tu wersja używająca pattern matching:
val to_words: Int => String = {
val a0 = ("one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen").split(' ')
val a1 = "twenty thirty forty fifty sixty seventy eighty ninety".split(' ')
(num: Int) => num match {
case n if n <= 19 => a0(n-1)
case n if n <= 99 => if (n % 10 != 0) "%s%s".format(a1((n-20)/10), a0(n % 10 - 1)) else a1((n-20)/10)
case n if n <= 999 => if (n % 100 != 0) "%shundredand%s".format(to_words(n/100), to_words(n % 100)) else "%shundred".format(to_words(n/100))
case n if n == 1000 => "onethousand"
case _ => "out of 1..1000"
}
}