public
Created

Fixnum/Bignum to_en function - convert numbers to English. Useful for testing your Euler 17 solution (hint, hint)

  • Download Gist
to_en.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
# Fixnum and Bignum :to_en function
# For Ruby Hack Night, May 7, 2012
# By David Andrews, Ryatta Group
 
class Unit
UNITS = [ "thousand", "million", "billion", "trillion", "quadrillion", "quintillion", "sextillion", "septillion", "octillion", "nonillion", "decillion", "undecillion", "duodecillion", "tredecillion", "quattuordecillion", "quindecillion", "sexdecillion", "septendecillion", "octodecillion", "novemdecillion", "vigintillion" ]
HUNDRED = "hundred and"
 
def self.how_big(zeroes)
return HUNDRED if zeroes == 2
return "" if zeroes < 3 || zeroes % 3 > 0 # if it ain't hundred, or a power of three, there's no name for it
zeroes /= 3
throw "toobig!" if zeroes >= UNITS.length
"#{UNITS[zeroes-1]},"
end
end
 
class Bignum
def to_en # handles massively large (possibly negative) values
return "negative #{(-self).to_en}" if self < 0
as_chars = self.to_s.split("")
chunk = self.to_s.length % 3
chunk = 3 if chunk == 0
text = ""
while as_chars.length > 0 # eat "chunks" until there are none left
text << "#{as_chars.shift(chunk).join.to_i.hundreds_to_en} #{Unit.how_big(as_chars.length)} "
chunk = 3
end
text
end
end
 
class Fixnum
ONES = [ "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty" ]
TENS = [ "ten", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety" ]
 
def to_en
9999999999999999999.coerce(self).first.to_en # a cheap way of achieving DRY -> defer to Bignum's to_en
end
 
def hundreds_to_en # handles the range [0, 999]
case self.to_s.length
when 3 # a number in the hundreds
"#{ONES[self/100]} #{Unit.how_big(2)} #{(self % 100).hundreds_to_en}"
when 2 # tens
return ONES[self] if self < ONES.length # teens
return "#{TENS[self/10-1]}-#{ONES[self % 10]}" if self % 10 > 0 # a compound name, if not a power of 10
TENS[self/10-1]
when 1 # ones
ONES[self]
end
end
end
 
puts "Gimme some numbers and I'll print them in English"
ARGF.each do |line|
puts line.to_i.to_en
end

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.