My Web Log Book

Project Euler Problem 17

This is a good way to learn Ruby by solving some problems from Project Euler. Here’s my solution to problem 17. Link to the problem - http://projecteuler.net/index.php?section=problems&id=17 and the problem text and solution are below:

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.

words = {
  0 => '',
  1 => 'one',
  2 => 'two',
  3 => 'three',
  4 => 'four',
  5 => 'five',
  6 => 'six',
  7 => 'seven',
  8 => 'eight',
  9 => 'nine',
  10 => 'ten',
  11 => 'eleven',
  12 => 'twelve',
  13 => 'thirteen',
  14 => 'fourteen',
  15 => 'fifteen',
  16 => 'sixteen',
  17 => 'seventeen',
  18 => 'eighteen',
  19 => 'nineteen',
  20 => 'twenty',
  30 => 'thirty',
  40 => 'forty',
  50 => 'fifty',
  60 => 'sixty',
  70 => 'seventy',
  80 => 'eighty',
  90 => 'ninety',
  100 => 'hundred',
  1000 => 'thousand'
}

total_letters = 0

(1..1000).each do |number|
  zero_padded_number = "%04d" % number
  digits = zero_padded_number.split(//).collect { |d| d.to_i }

  last_two_digits = digits[-2, 2].join.to_i

  thousands = words[digits[0]] + words[1000] if digits[0] != 0
  hundreds = words[digits[1]] + words[100] if digits[1] != 0
  _and_ = 'and' if (last_two_digits != 0 and number > 100)
  tens = last_two_digits >= 20 ? words[digits[2] * 10] + words[digits[3]] : words[last_two_digits]
  string = "#{thousands}#{hundreds}#{_and_}#{tens}"

  total_letters += string.length
end

puts total_letters