Simple ruby script to convert numbers to phrases. This serves as example script to teach basics of ruby.
Last active
February 16, 2018 22:18
-
-
Save deepredsky/0acb0636f4907a57a245f692977cacdc to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class NumberToPhrase | |
DIGIT_WORDS = | |
%w(zero | |
one | |
two | |
three | |
four | |
five | |
six | |
seven | |
eight | |
nine | |
ten | |
eleven | |
twelve | |
thirteen | |
fourteen | |
fifteen | |
sixteen | |
seventeen | |
eighteen | |
nineteen).freeze | |
TENS_WORDS = | |
%w(ten | |
twenty | |
thirty | |
forty | |
fifty | |
sixty | |
seventy | |
eighty | |
ninety).freeze | |
POSITION_WORDS = [nil, 'thousand', 'million', 'billion', 'trillion'].freeze | |
attr_reader :num | |
def initialize(num) | |
@num = num | |
end | |
def convert | |
return 'zero' if num.zero? | |
group_by_position(num).collect do |(group, place)| | |
number_part = group.reverse.join('').to_i | |
next unless number_part > 0 | |
phrase_part = _num_to_phrase(number_part) | |
[phrase_part, place] | |
end.flatten.compact.join ' ' | |
end | |
def to_s | |
convert | |
end | |
def self.[](num) | |
new(num).to_s | |
end | |
private | |
def group_by_position(num) | |
num | |
.digits | |
.each_slice(3) | |
.zip(POSITION_WORDS) | |
.reverse | |
end | |
def _num_to_phrase(num) | |
if num < 20 | |
DIGIT_WORDS[num] | |
elsif num < 100 | |
convert_tens(num) | |
else | |
convert_hundreds(num) | |
end | |
end | |
def convert_tens(num) | |
[TENS_WORDS[num / 10 - 1], | |
convert_remainder(num % 10)] | |
end | |
def convert_hundreds(num) | |
[ | |
"#{_num_to_phrase(num / 100)} hundred", | |
convert_remainder(num % 100) | |
] | |
end | |
def convert_remainder(remainder) | |
_num_to_phrase(remainder) if remainder > 0 | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require_relative 'number_to_phrase' | |
require 'minitest/autorun' | |
class NumberToPhraseTest < Minitest::Test | |
def test_zero | |
assert_equal 'zero', NumberToPhrase.new(0).to_s | |
end | |
def test_one | |
assert_equal 'one', NumberToPhrase.new(1).to_s | |
end | |
def test_8 | |
assert_equal 'eight', NumberToPhrase.new(8).to_s | |
end | |
def test_ten | |
assert_equal 'ten', NumberToPhrase.new(10).to_s | |
end | |
def test_18 | |
assert_equal 'eighteen', NumberToPhrase.new(18).to_s | |
end | |
def test_78 | |
assert_equal 'seventy eight', NumberToPhrase.new(78).to_s | |
end | |
def test_99 | |
assert_equal 'ninety nine', NumberToPhrase.new(99).to_s | |
end | |
def test_100 | |
assert_equal 'one hundred one', NumberToPhrase.new(101).to_s | |
end | |
def test_112 | |
assert_equal 'one hundred twelve', NumberToPhrase.new(112).to_s | |
end | |
def test_219 | |
assert_equal 'two hundred nineteen', NumberToPhrase.new(219).to_s | |
end | |
def test_515 | |
assert_equal 'five hundred fifteen', NumberToPhrase.new(515).to_s | |
end | |
def test_999 | |
assert_equal 'nine hundred ninety nine', NumberToPhrase.new(999).to_s | |
end | |
def test_919 | |
assert_equal 'nine hundred nineteen', NumberToPhrase.new(919).to_s | |
end | |
def test_145 | |
assert_equal 'one hundred forty five', NumberToPhrase.new(145).to_s | |
end | |
def test_1101 | |
assert_equal 'one thousand one hundred one', NumberToPhrase.new(1101).to_s | |
end | |
def test_34101 | |
assert_equal 'thirty four thousand one hundred one', NumberToPhrase.new(34_101).to_s | |
end | |
def test_134101 | |
assert_equal 'one hundred thirty four thousand one hundred one', NumberToPhrase.new(134_101).to_s | |
end | |
def test_100000 | |
assert_equal 'one hundred thousand', NumberToPhrase.new(100_000).to_s | |
end | |
def test_speed_of_light | |
assert_equal 'two hundred ninety nine million seven hundred ninety two thousand four hundred fifty eight', NumberToPhrase.new(299_792_458).to_s | |
end | |
def test_square_brackets | |
assert_equal 'eight', NumberToPhrase[8] | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment