Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- NUMBERS = {
- :a => 1,
- :one => 1,
- :two => 2,
- :three => 3,
- :four => 4,
- :five => 5,
- :six => 6,
- :seven => 7,
- :eight => 8,
- :nine => 9,
- :ten => 10,
- :eleven => 11,
- :twelve => 12,
- :thirteen => 13,
- :fourteen => 14,
- :fifteen => 15,
- :sixteen => 16,
- :seventeen => 17,
- :eighteen => 18,
- :nineteen => 19,
- :twenty => 20,
- :thirty => 30,
- :forty => 40,
- :fifty => 50,
- :sixty => 60,
- :seventy => 70,
- :eighty => 80,
- :ninety => 90,
- :hundred => 100,
- :thousand => 1000,
- :million => 1000000,
- :billion => 1000000000
- }
- # Decimas are stuff like million, hundred, thousand.
- # Also hundred thousand and hundred million.
- DECIMAS = [3,6,9].map { |n| 10 ** n }
- DECIMAS.concat [100] + DECIMAS.map { |n| n * 100 }
- def highest_decima(num)
- DECIMAS.select{ |d| d <= num }.max
- end
- NUMBERS.each do |meth, val|
- # Kernel.send :define_method instead of Kernel.define_method because it's
- # private. Truth be told, the |after| should be |*after| (and after=after[0]
- # afterwards) to avoid a warning about arity. The whole powernesting-of-
- # single-argument-methods thing kinda ruins the concept, though ;)
- Kernel.send(:define_method, meth) do |after|
- ret = if after
- after, is_decima = after if Array === after # See the `ret = [ret, ...] ...` line
- highest_decima = highest_decima(after)
- # if highest_decima < val, we are just adding digits (i.e. a "two-digit" method name)
- if highest_decima.nil? or highest_decima < val
- val + after
- else
- # This comment is too small to hold my elegant explanation for this.
- val * highest_decima + after - ((val < 10 or is_decima) ? highest_decima : 0)
- end
- else
- val
- end
- # Here's a little hack. Since there's no way of differentiating `million`
- # and `one million` (as in `twenty [one] million`), `million` returns the
- # value in an array just to distinguish it. It doesn't break the use since
- # decimas are never supposed to be used at the start of a number nesting
- # (use `one` or `a`). The :is_decima isn't needed per se, but hey;
- # shits'n'giggles!
- ret = [ret, :is_decima] if DECIMAS.include? val
- ret
- end
- end
- nineteen billion eight hundred six million five hundred forty three thousand two hundred ten # => 19806543210
- a thousand three # => 1003
- twenty one thousand three # => 21003
- twenty(thousand(three)) # => 20003
Add Comment
Please, Sign In to add comment