How to Implement a Humanize Counting Algorithm in Ruby
In this lesson, we are going to solve another complicated problem from Project Euler (question #17) that asks us to solve the question: If all the numbers from 1 to 1000 (one thousand) inclusive were written out in words, how many letters would be used?.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

In this lesson we are going to solve another complicated math problem using Ruby. The question we'll answer is:

If all the numbers from 1 to 1000 (one thousand) inclusive were written out in words, how many letters would be used?

Though this problem looks complex, it can be solved easily in Ruby using the humanize library. We'll start by including the humanize gem. If you don't have this gem in your system, install it by running: gem install humanize.

Now let's dive into the code:

require 'humanize'
no_space_array, total = [], 0
p (1..1000).to_a.map(&:humanize)

In the first line we're including the humanize gem. The next thing to do is set up some empty variables: no_space_array, total = [], 0. Then, we're building a range from 1 to 1000 and converting into an array. Last, we're calling the humanize method on this array by utilizing the map method. This will convert each element in the array to its named value.

If you execute now, the output is:

["one", "two", "three", "four", "five", "six", "seven", "eight"... "nine hundred and ninety-six", "nine hundred and ninety-seven", "nine hundred and ninety-eight", "nine hundred and ninety-nine", "one thousand"]

Pretty cool right? The humanize method takes every integer and converts it into words. Without this method, you'd have to write quite a bit of code to get the same output.

Next, we are going to iterate over the humanize array and call the delete method twice. The reason we are calling it twice is because we need to remove spaces and dashes.

(1..1000).to_a.map(&:humanize).each {no_space_array << word.delete(" ").delete("-")}
p no_space_array

First, we are going to call .each method. Then, we are going to delete all of the spaces. So the way you do that is word.delete(" ") and piping it into the no_space_array. We are also going to delete the dashes. We can simply chain this on: .delete("-").

You can print our string out and it will look like this:

"onetwothreefourfivesixseveneightnineteneleventwelve...ninetyeightninehundredandninetynineonethousand"

As you can see, it has combined each word and got rid of all the spaces and dashes.

Now, we are going to chain another iterator. This will go through our cleaned-up array and create the total for us. Here is the full program:

require 'humanize'

no_space_array, total = [], 0

(1..1000).to_a.map(&:humanize).each do |word|
  no_space_array << word.delete(" ").delete("-")
end.each { |element| total += element.length }

total # => 24527

We are going to take each element and the total, which starts at 0, and incrementally add onto each element length.

To determine the final count, print out the total. The correct answer is: 24,527.
If you went through that, great job!