Reputation: 5
I've written a program to take in a number, and print the number in english text. This is my second attempt, while trying to make it more condensed and repeat less.
The code works fine as long as the number is < 100 but over that, and I have issues. I tried removing the gets, and having a parameter on the method itself, but that moved the error from the line with the recursion, to line adding it's value to the variable total.
I think I'm at a point that my current skill isn't grasping. recursion still feels like dark magic to me.
def numberWords num
#num = gets.chomp.to_i
singles = ['one', 'two', 'three', 'four', 'five',
'six', 'seven', 'eight', 'nine']
tens = ['eleventy', 'twenty', 'thirty', 'forty', 'fifty',
'sixty', 'seventy', 'eighty', 'ninety']
teens = ['eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen',
'sixteen', 'seventeen', 'eighteen', 'nineteen']
total = ""
if num == 0
puts "Zero"
end
current = num/1000
if current > 0
thousands = numberWords current
total = total + thousands + "Thousands"
end
total = total + " "
current = num / 100
if current > 0
hundreds = numberWords current
total = total + hundreds + "Hundred"
end
total = total + " "
#TENS
current = num/10
if current > 1
total = total + tens[current - 1]
end
total = total + " "
#SINGLES
num = num - (current*10)
if num > 0
total = total + singles[num - 1]
end
puts total
end
numberWords(2222)
Upvotes: 0
Views: 70
Reputation: 5105
Try this version:
def number_words(num)
singles = ['one', 'two', 'three', 'four', 'five',
'six', 'seven', 'eight', 'nine']
tens = ['eleventy', 'twenty', 'thirty', 'forty', 'fifty',
'sixty', 'seventy', 'eighty', 'ninety']
teens = ['eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen',
'sixteen', 'seventeen', 'eighteen', 'nineteen']
if num == 0
return "zero"
elsif
num >= 1000
q, r = num.divmod(1000)
return number_words(q) + " thousand" + (r > 0 ? " " + number_words(r) : "")
elsif num >= 100
q, r = num.divmod(100)
return number_words(q) + " hundred" + (r > 0 ? " " + number_words(r) : "")
elsif num >= 20
q, r = num.divmod(10)
return tens[q - 1] + (r > 0 ? "-" + number_words(r) : "")
elsif num >= 11
r = num % 10
return teens[r - 1]
elsif num == 10
return "ten"
end
return singles[num - 1]
end
I changed it from puts output to building a string.
Important is the ordering, so if you want to handle millions and billions put those clauses in the correct order.
q and r are short for quotient and remainder.
The arithmetical if (condition ? true-statement : false-statement) is used to surpress "Zero" strings, where they should not be.
The basic idea is to handle what one can handle in an if clause and pass the other work recursively to one self.
Here are some outputs:
0: zero
1: one
2: two
3: three
10: ten
11: eleven
12: twelve
13: thirteen
20: twenty
21: twenty-one
22: twenty-two
23: twenty-three
30: thirty
39: thirty-nine
99: ninety-nine
100: one hundred
101: one hundred one
123: one hundred twenty-three
221: two hundred twenty-one
990: nine hundred ninety
999: nine hundred ninety-nine
1000: one thousand
2222: two thousand two hundred twenty-two
Upvotes: 1