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

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'

(1..1000).to_a.map(&:humanize)

In the first line we're including the humanize gem. On the next line we're building a range from 1 to 1000, and converting into an array. Lastly 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 remove all of the dashes and spaces by leveraging the little known tr method. The tr method is short for translate and has some similarities to gsub.

(1..1000).to_a.map(&:humanize).join.tr(" -", "")

In this code we're calling the join method to convert the array into a giant string. From there we're removing the spaces and dashes by passing them as arguments to the tr method.

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

"onetwothreefourfivesixseveneightnineteneleventwelve...ninetyeightninehundredandninetynineonethousand"

Now all we have to do is call the size method on our string to get the total number of characters. Running the program will return a value of 21124, which is the correct answer.