Guest User

Untitled

a guest
Feb 21st, 2018
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.46 KB | None | 0 0
  1. NUMBERS = {
  2. :a => 1,
  3. :one => 1,
  4. :two => 2,
  5. :three => 3,
  6. :four => 4,
  7. :five => 5,
  8. :six => 6,
  9. :seven => 7,
  10. :eight => 8,
  11. :nine => 9,
  12. :ten => 10,
  13. :eleven => 11,
  14. :twelve => 12,
  15. :thirteen => 13,
  16. :fourteen => 14,
  17. :fifteen => 15,
  18. :sixteen => 16,
  19. :seventeen => 17,
  20. :eighteen => 18,
  21. :nineteen => 19,
  22. :twenty => 20,
  23. :thirty => 30,
  24. :forty => 40,
  25. :fifty => 50,
  26. :sixty => 60,
  27. :seventy => 70,
  28. :eighty => 80,
  29. :ninety => 90,
  30. :hundred => 100,
  31. :thousand => 1000,
  32. :million => 1000000,
  33. :billion => 1000000000
  34. }
  35.  
  36. # Decimas are stuff like million, hundred, thousand.
  37. # Also hundred thousand and hundred million.
  38. DECIMAS = [3,6,9].map { |n| 10 ** n }
  39. DECIMAS.concat [100] + DECIMAS.map { |n| n * 100 }
  40.  
  41. def highest_decima(num)
  42. DECIMAS.select{ |d| d <= num }.max
  43. end
  44.  
  45. NUMBERS.each do |meth, val|
  46. # Kernel.send :define_method instead of Kernel.define_method because it's
  47. # private. Truth be told, the |after| should be |*after| (and after=after[0]
  48. # afterwards) to avoid a warning about arity. The whole powernesting-of-
  49. # single-argument-methods thing kinda ruins the concept, though ;)
  50. Kernel.send(:define_method, meth) do |after|
  51. ret = if after
  52. after, is_decima = after if Array === after # See the `ret = [ret, ...] ...` line
  53. highest_decima = highest_decima(after)
  54.  
  55. # if highest_decima < val, we are just adding digits (i.e. a "two-digit" method name)
  56. if highest_decima.nil? or highest_decima < val
  57. val + after
  58. else
  59. # This comment is too small to hold my elegant explanation for this.
  60. val * highest_decima + after - ((val < 10 or is_decima) ? highest_decima : 0)
  61. end
  62. else
  63. val
  64. end
  65.  
  66. # Here's a little hack. Since there's no way of differentiating `million`
  67. # and `one million` (as in `twenty [one] million`), `million` returns the
  68. # value in an array just to distinguish it. It doesn't break the use since
  69. # decimas are never supposed to be used at the start of a number nesting
  70. # (use `one` or `a`). The :is_decima isn't needed per se, but hey;
  71. # shits'n'giggles!
  72. ret = [ret, :is_decima] if DECIMAS.include? val
  73.  
  74. ret
  75. end
  76. end
  77.  
  78. nineteen billion eight hundred six million five hundred forty three thousand two hundred ten # => 19806543210
  79. a thousand three # => 1003
  80. twenty one thousand three # => 21003
  81. twenty(thousand(three)) # => 20003
Add Comment
Please, Sign In to add comment