Instantly share code, notes, and snippets.

# k00ka/to_en.rb Created May 8, 2012

Fixnum/Bignum to_en function - convert numbers to English. Useful for testing your Euler 17 solution (hint, hint)
 # 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