0

I made a program in Ruby and I have no idea why it's not giving me the correct answer

Problem: 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.

My code:

def number_to_words(n)
    custom = {"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",}
    tens = {"0" => "", "1" => "ten", "2" => "twenty", "3" => "thirty", "4" => "forty", "5" => "fifty", "6" => "sixty", "7" => "seventy", "8" => "eighty", "9" => "ninety"}
    if n < 20 
        string = custom[n.to_s]     
    elsif n >= 20  &&  n < 100      
        string = tens[n.to_s[0]] + custom[n.to_s[1]]
    elsif n % 1000 == 0
        string = "onethousand"
    elsif n >= 100 && n % 100 == 0 
        string = custom[n.to_s[0]] + "hundred"
    else
        string = custom[n.to_s[0]] + "hundred" + "and" + tens[n.to_s[1]] + custom[n.to_s[2]]
    end
end

def letter_counter(x)
    n = 1
    sum = 0
    while n < x + 1
        sum = sum + number_to_words(n).length
        print number_to_words(n).length, "\n"
        n = n + 1
        print n, "\n"
    end
    results = sum
end

Correct answer is

21124

Richard Hamilton
  • 25,478
  • 10
  • 60
  • 87
  • It doesn't quite match SO format. You'd better ask this question on http://codereview.stackexchange.com/ – phts Apr 06 '15 at 12:19
  • 1
    @phts that is not correct. This code is not working as intended and thus off-topic for codereview. Please read: http://meta.stackoverflow.com/questions/253975/be-careful-when-recommending-code-review-to-askers . Thanks! – Vogel612 Apr 06 '15 at 12:21

3 Answers3

3

I don't really know Ruby, but I do know this Euler question. After studying your code that you have, I would have to guess that your else statement is incorrect.

Say you have the number 111, which I think falls into your else statement. You wind up building a string that says, "onehundredandtenone" instead of "onehundredandeleven"

So it would look to me that the range from 111 - 119 would have incorrect strings built which will throw off your counts. Actually, this would be true for 211 - 219... 311 - 319... etc...

Shar1er80
  • 9,001
  • 2
  • 20
  • 29
0

You can use the humanize gem:

require 'humanize'

p (1..1000).to_a.map(&:humanize).join.tr(" -", "").size
Arif
  • 712
  • 11
  • 20
0

I don't know if you've already knew what was wrong, but I debugged it.

The problem happened around 111-120, 211-220, 311-320... E.g. number_to_words(111) became "onehundredandtenone"

So I added two more lines to take into account these instances.

Here's the modification:

def number_to_words(n)

custom = {"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",}
tens = {"0" => "", "1" => "ten", "2" => "twenty", "3" => "thirty", "4" => "forty", "5" => "fifty", "6" => "sixty", "7" => "seventy", "8" => "eighty", "9" => "ninety"}
if n < 20 
  string = custom[n.to_s]     
elsif n >= 20  &&  n < 100      
    string = tens[n.to_s[0]] + custom[n.to_s[1]] 
elsif n == 1000
    string = "onethousand"
elsif n >= 100 && n % 100 == 0 
    string = custom[n.to_s[0]] + "hundred"
#changed this part
elsif n >= 100 && (n % 100 < 20)
    string = custom[n.to_s[0]] + "hundred" + "and" + custom[(n % 100).to_s[(0..1)]] 
else
    string = custom[n.to_s[0]] + "hundred" + "and" + tens[n.to_s[1]] + custom[n.to_s[2]]
    end
    return string
end
C-likethis123
  • 31
  • 1
  • 5