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}."