Last active
September 23, 2019 20:39
-
-
Save pedrogimenez/6096235 to your computer and use it in GitHub Desktop.
string calculator
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
| module StringCalculator | |
| extend self | |
| DELIMITERS = ["\n", ","] | |
| DELIMITER_MARK = '//' | |
| def add(string) | |
| numbers = extract_numbers(string) | |
| assert_not_negatives(numbers) | |
| total(numbers) | |
| end | |
| private | |
| def extract_numbers(string) | |
| string.split(delimiters(string)).map(&:to_i) | |
| end | |
| def delimiters(string) | |
| Regexp.union(delimiters_regexp(string)) | |
| end | |
| def delimiters_regexp(string) | |
| regexp = DELIMITERS.tap do |delimiters| | |
| delimiters << string[DELIMITER_MARK.length] if string.start_with?(DELIMITER_MARK) | |
| end | |
| end | |
| def assert_not_negatives(numbers) | |
| negatives = numbers.select { |number| number < 0} | |
| raise "negatives are not allowed: #{negatives.join(', ')}" if negatives.size > 0 | |
| end | |
| def total(numbers) | |
| numbers.inject(0, :+) | |
| end | |
| end | |
| describe StringCalculator do | |
| context 'empty string' do | |
| it 'returns 0 for ""' do | |
| subject.add('').should eq(0) | |
| end | |
| end | |
| context 'simple number' do | |
| it 'returns 1 for "1"' do | |
| subject.add('1').should eq(1) | |
| end | |
| it 'returns 2 for "2"' do | |
| subject.add('2').should eq(2) | |
| end | |
| end | |
| context 'two numbers' do | |
| it 'returns 3 for "1,2"' do | |
| subject.add('1,2').should eq(3) | |
| end | |
| it 'returns 5 for "2,3"' do | |
| subject.add('2,3').should eq(5) | |
| end | |
| it 'returns 12 for "10,2"' do | |
| subject.add('10,2').should eq(12) | |
| end | |
| end | |
| context 'three numbers' do | |
| it 'returns 3 for "1,1,1"' do | |
| subject.add('1,1,1').should eq(3) | |
| end | |
| end | |
| context 'with line break' do | |
| it 'returns 5 for "2\n3"' do | |
| subject.add("2\n3").should eq(5) | |
| end | |
| it 'returns 9 for "3\n3,3"' do | |
| subject.add("3\n3,3").should eq(9) | |
| end | |
| end | |
| context 'with custom delimiter' do | |
| it 'returns 10 for "//;\n5;5"' do | |
| subject.add("//;\n5;5").should eq(10) | |
| end | |
| end | |
| context 'with negative numbers' do | |
| it 'throws error with the list of the negative numbers' do | |
| expect { subject.add('-1,-2,-3') }.to raise_exception( | |
| 'negatives are not allowed: -1, -2, -3') | |
| end | |
| end | |
| it 'integration' do | |
| subject.add("//;\n5;5\n2,3,300\n1000").should eq(1315) | |
| end | |
| end |
Author
Couple of improvements and simplifications. https://gist.github.com/pasku/90f9138bdb37af5dc99b
Author
@pasku I have applied some of your improvements here :-)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I did some improvements :-)