Problem
https://projecteuler.net/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.
Answer: 21124
Solution
require 'humanize'
def simple_humanize_length(number)
raise ArgumentError, 'Only supports (1..99999)' unless (1..99_999).cover?(number)
result = ''
working = number
while working.positive?
case working
when (1000..99_999)
how_many = (working / 1000).floor
working -= 1000 * how_many
result += "#{simple_humanize_length(how_many)}thousand"
when (100..999)
how_many = (working / 100).floor
working -= 100 * how_many
result += "#{simple_humanize_length(how_many)}hundred#{'and' unless working.zero?}"
when (20..99)
how_many = (working / 10).floor
working -= 10 * how_many
result += case how_many
when 4, 5, 6 # forty, fifty, sixty = 5
'aaaaa'
when 2, 3, 8, 9 # twenty, thirty, eighty, ninety = 6
'bbbbbb'
when 7 # seventy = 7
'ccccccc'
end
else
result += case working
when 1, 2, 6, 10 # one, two, six, ten = 3
'ddd'
when 4, 5, 9 # four, five, nine = 4
'eeee'
when 3, 7, 8 # three, seven, eight = 5
'fffff'
when 11, 12 # eleven, twelve = 6
'gggggg'
when 15, 16 # fifteen, sixteen = 7
'hhhhhhh'
when 13, 14, 18, 19 # thirteen, fourteen, eighteen, nineteen = 8
'iiiiiiii'
when 17
'jjjjjjjjj' # seventeen = 9
end
working = 0
end
end
result
end
def number_letter_counts(upper)
(1..upper).reduce(0) do |sum, digit|
sum + simple_humanize_length(digit).length
end
end
def number_letter_counts_cheat(upper)
(1..upper).reduce(0) { |sum, digit| sum + digit.humanize.tr(' -', '').length }
end
puts "Mine: #{number_letter_counts(1000)}" if __FILE__ == $PROGRAM_NAME
puts "Cheat: #{number_letter_counts_cheat(1000)}" if __FILE__ == $PROGRAM_NAME