Snippet

project_euler/17.rb
Code:
# Project Euler Problem 17: Number Letter Counts

# 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?

def number_to_words(n)
    result, words = [], {
        0 => "zero", 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",
    }
    # Thousands
    thousands, n = (n / 1000).floor, n % 1000
    result += [words[thousands], words[1000]] if thousands > 0
    result << "and" if (n > 0) && (thousands > 0)
    # Hundreds
    hundreds, n = (n / 100).floor, n % 100
    result += [words[hundreds], words[100]] if hundreds > 0
    result << "and" if (n > 0) && (hundreds > 0)
    # Tens & Ones
    result += words.key?(n) ? [words[n]] : [words[n - (n % 10)], words[n % 10]] if n > 0
    return result
end

def solve(n)
    (1..n).map { |m| number_to_words(m) }.join.size
end

puts solve(5)
puts solve(1000)
Output:
19
21124