Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions gaizka/string_calculator/.rvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rvm --create use ruby-1.9.2@12katas
43 changes: 43 additions & 0 deletions gaizka/string_calculator/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
StringCalculator, ruby version

To test it:

gem install rspec

rspec -f documentation string_calculator_spec.rb

Expected output:

$ rspec -f documentation string_calculator_spec.rb

StringCalculator
(for an empty string it will return 0)
simple sums
any number of ints
should work using different delimiters ("1,2,3")
should work using different delimiters ("1\n2\n3")
should work using different delimiters ("1,2\n3")
should work using different delimiters ("1\n2,3")
should work using a custom delimiter ("//;\n1;2;3")
should work using a custom delimiter ("//,\n1,2,3")
should work using a custom delimiter ("//\n\n1\n2\n3")
should work using a custom delimiter ("//z\n1z2z3")
should work using a custom delimiter ("//+\n1+2+3")
should work using a custom delimiter ("//.\n1.2.3")
should work using a custom delimiter ("//*\n1*2*3")
should work using a custom delimiter ("//[\n1[2[3")
should raise an error when there are negatives ("//;\n1;2;-3;-4;5;6")
should raise an error when there are negatives ("1,2,-3,3,-4")
should ignore integers bigger than 1000
should support multiple-length delimiters ("//[***]\n1***2***3")
should support multiple-length delimiters ("//[**]\n1**2**3")
should support multiple-length delimiters ("//[*]\n1*2*3")
should support 1-char different delimiters ("//[;][,][z][.][*]\n1;2,3.4*5")
should support 1-char different delimiters ("//[z][x][.]\n1.2z3x4x5")
should support multiple-char different delimiters ("//[**][,,,][;;;]\n1**2,,,3;;;4,,,5")
should support multiple-char different delimiters ("//[,,][*][zzz]\n1,,2*3*4zzz5")
should support multiple-char different delimiters ("//[**][..][++]\n1**2++3..4++5")

Finished in 0.01664 seconds
26 examples, 0 failures

60 changes: 60 additions & 0 deletions gaizka/string_calculator/string_calculator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@

# Ejercicios 1 y 2
class StringCalculator_version1_and_2
def add(string)
string.split(",").map{|n| n.to_i}.inject(0) do |acc, item|
acc + item
end
end
end

# Ejercicio 3
class StringCalculator_version_3
def add(string)
return 0 if string.nil? || string.empty?

string.split(/[,\n]/).map{|n| n.to_i}.inject(0) do |acc, item|
acc + item
end
end
end

# Válido para todos
class StringCalculator

DefaultDelimiter = /[,\n]/

def add(string)
return 0 if string.nil? || string.empty?

delimiter = extract_delimiter!(string) || DefaultDelimiter

integers = string.split(delimiter).map{|n| n.to_i}

if ! (negatives = integers.select{|i| i < 0}).empty?
raise StandardError.new "negatives not allowed: #{negatives.join(",")}"
end

integers.inject(0) do |acc, item|
acc + (item <= 1000 ? item : 0)
end
end

private
def extract_delimiter!(string)

# No header
return nil unless string.slice! %r{^//(.+)\n}

# 1 char case: $1 now is
return $1 if $1.size == 1

# What to do if header is: "//[\n" ??

# multiple [**][,][zzz] delimiters
delimiters = $1.scan(/\[([^\]]+)\]/).flatten

# Build a new regexp joining them: **|,|zzz . Escape special chars!!
Regexp.new(delimiters.map{|d| Regexp.escape(d)}.join("|"))
end
end
68 changes: 68 additions & 0 deletions gaizka/string_calculator/string_calculator_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
$: << File.dirname(__FILE__)

require 'string_calculator'

describe StringCalculator do
it "(for an empty string it will return 0)" do
subject.add("").should == 0
subject.add("0").should == 0
end

it "simple sums" do
subject.add("1").should == 1
subject.add("1,2").should == 3
end

it "any number of ints" do
subject.add( ([2] * 10).join(",")).should == 20
end

["1,2,3", "1\n2\n3", "1,2\n3", "1\n2,3"].each do |valid|
it "should work using different delimiters (#{valid.inspect})" do
subject.add(valid).should == 6
end
end

[";", ",", "\n", "z", "+", ".", "*", "["].each do |sep|
test = "//#{sep}\n" + [1,2,3].join(sep)
it "should work using a custom delimiter (#{test.inspect})" do
subject.add(test).should == 6
end
end

["//;\n1;2;-3;-4;5;6", "1,2,-3,3,-4"].each do |neg|
it "should raise an error when there are negatives (#{neg.inspect})" do
expect {
subject.add(neg)
}.to raise_error(StandardError, /negatives not allowed: -3,-4/)
end
end

it "should ignore integers bigger than 1000" do
subject.add("//;\n1;2;1000;1001;3").should == 1006
end

["//[***]\n1***2***3", "//[**]\n1**2**3", "//[*]\n1*2*3"].each do |test|
it "should support multiple-length delimiters (#{test.inspect})" do
subject.add(test).should == 6
end
end

["//[;][,][z][.][*]\n1;2,3.4*5", "//[z][x][.]\n1.2z3x4x5"].each do |test|
it "should support 1-char different delimiters (#{test.inspect})" do
subject.add(test).should == 15
end
end

[
"//[**][,,,][;;;]\n1**2,,,3;;;4,,,5",
"//[,,][*][zzz]\n1,,2*3*4zzz5",
"//[**][..][++]\n1**2++3..4++5",
].each do |test|
it "should support multiple-char different delimiters (#{test.inspect})" do
subject.add(test).should == 15
end
end

end