Skip to content

Instantly share code, notes, and snippets.

@pedrogimenez
Last active September 23, 2019 20:39
Show Gist options
  • Select an option

  • Save pedrogimenez/6096235 to your computer and use it in GitHub Desktop.

Select an option

Save pedrogimenez/6096235 to your computer and use it in GitHub Desktop.
string calculator
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
@pedrogimenez
Copy link
Copy Markdown
Author

I did some improvements :-)

@gpg0
Copy link
Copy Markdown

gpg0 commented Jul 27, 2013

Couple of improvements and simplifications. https://gist.github.com/pasku/90f9138bdb37af5dc99b

@pedrogimenez
Copy link
Copy Markdown
Author

pedrogimenez commented Jul 27, 2013

@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