From: Eliah Hecht Date: 2005-03-28T10:01:25+09:00 Subject: [SOLUTION] English Numerals (#25) This is my first submitted solution, and I hope I've figured the time zones right and it's actually been 48 hours. Also, I haven't been coding Ruby (or at all) for all that long, so I hope my code is decent. It was a fun quiz. I had to choose some rules that don't quite match up with natural speech in my dialect, since I was unable to pin down systematically what the rules for my dialect are. (I say "nine hundred one", but "two hundred and one", for instance. It's just odd.) Anyway, without further ado: class Integer def teen case self when 0: "ten" when 1: "eleven" when 2: "twelve" else in_compound + "teen" end end def ten case self when 1: "ten" when 2: "twenty" else in_compound + "ty" end end def in_compound case self when 3: "thir" when 5: "fif" when 8: "eigh" else to_en end end def to_en(ands=true) small_nums = [""] + %w[one two three four five six seven eight nine] if self < 10: small_nums[self] elsif self < 20: (self % 10).teen elsif self < 100: result = (self/10).ten result += "-" if (self % 10) != 0 result += (self % 10).to_en return result elsif self < 1000 if self%100 != 0 and ands (self/100).to_en(ands)+" hundred and "+(self%100).to_en(ands) else ((self/100).to_en(ands)+ " hundred "+(self%100).to_en(ands)).chomp(" ") end else front,back = case (self.to_s.length) % 3 when 0: [0..2,3..-1].map{|i| self.to_s[i]}.map{|i| i.to_i} when 2: [0..1,2..-1].map{|i| self.to_s[i]}.map{|i| i.to_i} when 1: [0..0,1..-1].map{|i| self.to_s[i]}.map{|i| i.to_i} end degree = [""] + %w[thousand million billion trillion quadrillion quintillion sextillion septillion octillion nonillion decillion undecillion duodecillion tredecillion quattuordecillion quindecillion sexdecillion septdecillion novemdecillion vigintillion unvigintillion duovigintillion trevigintillion quattuorvigintillion quinvigintillion sexvigintillion septvigintillion octovigintillion novemvigintillion trigintillion untregintillion duotrigintillion googol] result = front.to_en(false) + " " + degree[(self.to_s.length-1)/3] result += if back > 99: ", " elsif back > 0: ands ? " and " : " " else "" end result += back.to_en(ands) return result.chomp(" ") end end end # I'm not really happy about re-defining degree, but I couldn't figure # out where to put it so it would be available both places I use it. degree = [""] + %w[thousand million billion trillion quadrillion quintillion sextillion septillion octillion nonillion decillion undecillion duodecillion tredecillion quattuordecillion quindecillion sexdecillion septdecillion novemdecillion vigintillion unvigintillion duovigintillion trevigintillion quattuorvigintillion quinvigintillion sexvigintillion septvigintillion octovigintillion novemvigintillion trigintillion untregintillion duotrigintillion googol] medium_nums = (1..999).map{|i| i.to_en} print "The alphabetically first number (1-999) is: " puts first = medium_nums.min.dup first_degree = degree[1..-1].min first << " " + first_degree puts "The first non-empty degree word (10**3-10**100) is: "+first_degree next_first = (["and"] + medium_nums).min first << " " + next_first puts "The next first word (numbers 1-999 + 'and') is: "+next_first if next_first == "and" puts "Since the last word was 'and', we need an odd number in 1..99." odd_nums = [] (0..98).step(2){|i| odd_nums << medium_nums[i]} first_odd = odd_nums.min puts "The first one is: "+first_odd first << " " + first_odd else # This will never happen; I can't bring myself to write it. end puts "Our first odd number, then, is #{first}."