Created
May 8, 2012 21:37
-
-
Save k00ka/2639531 to your computer and use it in GitHub Desktop.
Fixnum/Bignum to_en function - convert numbers to English. Useful for testing your Euler 17 solution (hint, hint)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment