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 |
I did some improvements :-)
Couple of improvements and simplifications. https://gist.github.com/pasku/90f9138bdb37af5dc99b
@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
Creo que no necesitamos guardar los delimiters en la clase Numbers, puesto que solo se usan en el initialize (que los tiene como parametro tambien) y en el parse, que es privado. Fijate que nunca llamamos al getter. Sería mejor pasarlo como parametro al parse.
Por otro lado, algo que he estado pensando es en el parse_numbers. numbers es redundante( la clase ya te lo dice) y ademas, no parsea, extrae.