Guest User

Untitled

a guest
Jul 19th, 2018
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.91 KB | None | 0 0
  1. require 'minitest/autorun'
  2. require 'humanize'
  3.  
  4. class NumberConverter
  5. DICTIONARY = {
  6. 0 => 'zero',
  7. 1 => 'one',
  8. 2 => 'two',
  9. 3 => 'three',
  10. 4 => 'four',
  11. 5 => 'five',
  12. 6 => 'six',
  13. 7 => 'seven',
  14. 8 => 'eight',
  15. 9 => 'nine',
  16. 10 => 'ten',
  17. 11 => 'eleven',
  18. 12 => 'twelve',
  19. 13 => 'thirteen',
  20. 14 => 'fourteen',
  21. 15 => 'fifteen',
  22. 16 => 'sixteen',
  23. 17 => 'seventeen',
  24. 18 => 'eighteen',
  25. 19 => 'nineteen',
  26. 20 => 'twenty',
  27. 30 => 'thirty',
  28. 40 => 'fourty',
  29. 50 => 'fifty',
  30. 60 => 'sixty',
  31. 70 => 'seventy',
  32. 80 => 'eighty',
  33. 90 => 'ninety',
  34. 10**2 => 'hundred',
  35. 10**3 => 'thousand',
  36. 10**6 => 'million',
  37. 10**9 => 'billion',
  38. 10**12 => 'trillion',
  39. 10**15 => 'quadrillion',
  40. 10**18 => 'quintillion',
  41. 10**21 => 'sextillion',
  42. }
  43.  
  44. def self.validate(number)
  45. raise("Sorry, I only know how to handle integers") unless number.is_a?(Integer)
  46. raise("Sorry, that's too big") if number > 10**21
  47. raise("Sorry, no negative numbers") if number < 0
  48. end
  49.  
  50. def self.spacer(number)
  51. if number < 100
  52. ' and '
  53. else
  54. ', '
  55. end
  56. end
  57.  
  58. def self.convert(number)
  59. validate(number)
  60.  
  61. case
  62. when number < 20
  63. DICTIONARY[number]
  64.  
  65. when number < 100
  66. digit = number / 10 * 10
  67. remainder = number % 10
  68.  
  69. if remainder == 0
  70. "#{DICTIONARY[digit]}"
  71. else
  72. "#{DICTIONARY[digit]}-#{DICTIONARY[remainder]}"
  73. end
  74.  
  75. else
  76. power = Math.log10(number).to_i
  77. if power > 2
  78. # Every third power of 10, break the number up to call convert
  79. # on its component parts. e.g. 23,432 --> "Twenty three thousand..."
  80.  
  81. power -= power % 3
  82. end
  83.  
  84. digit = number / 10**power
  85. remainder = number % 10**power
  86.  
  87. if remainder != 0
  88. remainder_text = "#{spacer(remainder)}#{convert(remainder)}"
  89. end
  90.  
  91. "#{convert(digit)} #{DICTIONARY[10**power]}#{remainder_text}"
  92. end
  93. end
  94. end
  95.  
  96. class TestNumberConverter < Minitest::Test
  97. describe NumberConverter do
  98. def check_number(number)
  99. output = NumberConverter.convert(number)
  100. assert_equal(number.humanize, output)
  101. end
  102.  
  103. describe "invalid numbers" do
  104. it "can't handle floats" do
  105. assert_raises RuntimeError do
  106. NumberConverter.convert(4.3)
  107. end
  108. end
  109.  
  110. it "can't handle more than a sextillion" do
  111. assert_raises RuntimeError do
  112. NumberConverter.convert(10**22)
  113. end
  114. end
  115.  
  116. it "can't handle negative numbers" do
  117. assert_raises RuntimeError do
  118. NumberConverter.convert(-50)
  119. end
  120. end
  121. end
  122.  
  123. describe "valid integers" do
  124. it "knows 0" do
  125. check_number(0)
  126. end
  127.  
  128. it "knows 3" do
  129. check_number(3)
  130. end
  131.  
  132. it "knows 10" do
  133. check_number(10)
  134. end
  135.  
  136. it "knows 13" do
  137. check_number(13)
  138. end
  139.  
  140. it "knows 23" do
  141. check_number(23)
  142. end
  143.  
  144. it "knows 70" do
  145. check_number(70)
  146. end
  147.  
  148. it "knows 300" do
  149. check_number(300)
  150. end
  151.  
  152. it "knows 429" do
  153. check_number(429)
  154. end
  155.  
  156. it "knows 3000" do
  157. check_number(3000)
  158. end
  159.  
  160. it "knows 3429" do
  161. check_number(3429)
  162. end
  163.  
  164. it "knows 10,009" do
  165. check_number(10009)
  166. end
  167.  
  168. it "knows 67,009" do
  169. check_number(67009)
  170. end
  171.  
  172. it "knows 403,209" do
  173. check_number(403229)
  174. end
  175.  
  176. it "knows 1,403,209" do
  177. check_number(1403229)
  178. end
  179.  
  180. it "knows 10,403,219" do
  181. check_number(10403219)
  182. end
  183.  
  184. it "knows 400,003,219,001" do
  185. check_number(400003219001)
  186. end
  187.  
  188. it "knows 10,400,403,219,321" do
  189. check_number(10400403219321)
  190. end
  191.  
  192. it "knows 10,000,400,403,219,321" do
  193. check_number(10000400403219321)
  194. end
  195.  
  196. it "knows 10**21" do
  197. check_number(10**21)
  198. end
  199. end
  200. end
  201. end
Add Comment
Please, Sign In to add comment