Skip to content

Commit

Permalink
Merge pull request #102 from enriclluelles/enriclluelles
Browse files Browse the repository at this point in the history
Mas vale tarde que nunca :)
  • Loading branch information
12meses12katas committed Nov 6, 2011
2 parents 93bb5e3 + 3aa79be commit 8be61d2
Show file tree
Hide file tree
Showing 3 changed files with 188 additions and 0 deletions.
79 changes: 79 additions & 0 deletions enriclluelles/javascript/string_calculator.js
@@ -0,0 +1,79 @@
assert = require("assert");

//taken from http://simonwillison.net/2006/Jan/20/escape/
RegExp.escape = function(text) {
return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
}

StringCalculator = (function () {
var parseString = function (s) {
var tmp = s;
var scan;
var delimiters = /,|\n/

scan = s.match(/^\/\/(\[.+\])+\n/);
//checking if there's a delimiter definition
if (scan) {
scan = scan[1];
delimiters = []
pattern = /\[([^\[\]]+)\]/g
while(tmp = (pattern).exec()){
delimiters.push(RegExp.escape(tmp[1]));
}
delimiters = delimiters.join("|")
delimiters = new RegExp(delimiters);
tmp = s.split("\n"); tmp.shift();
tmp = tmp.join();
}
return tmp.split(delimiters);
};

var negatives;

var checkNum = function (n) {
if (n < 0) {
negatives.push(n);
return false;
}
if (n > 1000) {
return false;
}
return true;
}

return {
add: function (numbers) {
var nums;
var sum = 0;
if (numbers === "") {
return 0;
}

negatives = [];

nums = parseString(numbers);
for (i = 0; i < nums.length; i++) {
if (checkNum(nums[i])) {
sum = sum + parseInt(nums[i]);
}
}

if (negatives.length > 0) {
throw new Error("Tried to add negatives: " + negatives.join(","));
}

return sum;
}
};
})();

assert.equal(StringCalculator.add(""),0);
assert.equal(StringCalculator.add("1,2,3"),6);
assert.equal(StringCalculator.add("//[me]\n1me2"),3);
assert.equal(StringCalculator.add("//[*]\n1*2"),3);
assert.equal(StringCalculator.add("//[*][hola]\n1*2hola1001"),3);
try {
StringCalculator.add("//[me]\n-1me-2");
console.log("Something went wrong, this message shouldn't be printed");
}
catch (Error) {}
51 changes: 51 additions & 0 deletions enriclluelles/python/string_calculator.py
@@ -0,0 +1,51 @@
import re
from nose.tools import *

class StringCalculator:
def add(self,s):
if s == "": return 0
(delimiter,st) = self.__find_delimiter(s)
numbers = [int(x) for x in re.split(delimiter, st)]
negatives = [x for x in numbers if x < 0] #collect the negatives to show them after
if negatives:
raise Exception("Tried to add negatives: %s" % negatives)
to_sum = [x for x in numbers if x <= 1000]
return sum(to_sum)

def __find_delimiter(self,s):
pattern = "^//(\[.+\])+\n"
scan = re.search(pattern, s)
if scan: #find out if we have custom delimiters
#we make a regexp with delimiters: (ex) *|,|??
delimiters = "|".join([ re.escape(dl) for dl in re.findall("\[([^\[\]]+)\]",
scan.group(1)) ])
return delimiters, re.sub(pattern,"",s)
return ",|\n",s

class TestStringCalculator:
def setUp(self):
self.s = StringCalculator()

def test_empty(self):
assert self.s.add("") == 0

def test_simple(self):
assert self.s.add("1,2,3") == 6

def test_with_carriage(self):
assert self.s.add("1,2\n3") == 6

def test_big_stuff(self):
assert self.s.add("1"+",1"*1000) == 1001

def test_custom_delimiters(self):
assert self.s.add("//[o][hai]\n1o2o34hai0") == 37

def test_custom_special_delimiters(self):
assert self.s.add("//[??][*]\n1*2*34??0") == 37

def test_negatives(self):
assert_raises(Exception, self.s.add, "//*\n-1*-1*3")

def test_no_more_than_one_thousand(self):
assert self.s.add("1,2,3,1001") == 6
58 changes: 58 additions & 0 deletions enriclluelles/ruby/string_calculator.rb
@@ -0,0 +1,58 @@
class StringCalculator
def add s
return 0 if s.to_s == ""
st, delimiters = find_delimiter s
numbers = st.split(delimiters).map(&:to_i)
negatives = numbers.select{|n| n < 0}
raise Exception.new("Tried to add negatives: #{negatives.to_s}") if negatives.any?
numbers.select{|n| n <= 1000 }.inject(0){|sum,x| sum += x}
end

private
def find_delimiter s
if (s =~ %r{^//(.+)\n})
pattern = $& #we grab the full match to remove it from the string
delimiters = $1.scan(/\[([^\[\]]+)\]/).flatten.compact #parse the delimiters between the brackets
delimiters = delimiters.map{|d| Regexp.escape(d)}.join("|")
return s.gsub(pattern,''), Regexp.new(delimiters)
end
return s, /,|\n/
end
end

require 'minitest/spec'
require 'minitest/autorun'

describe StringCalculator do
before do
@sc = StringCalculator.new
end

describe "when adding regular strings" do
it "should add the empty string" do
@sc.add("").must_equal 0
end
it "should add comma-separated numbers" do
@sc.add("1,2,3").must_equal 6
end
it "should add comma and carraige-separated numbers" do
@sc.add("1,2,3\n4").must_equal 10
end
end

describe "when adding string with custom delimiter" do
it "should use the custom delimiter" do
@sc.add("//[n][mmmm]\n1n2n3").must_equal 6
end
it "should use the custom delimiter even if its a special char" do
@sc.add("//[*]\n1*2*3").must_equal 6
@sc.add("//[*][????]\n50*49????1").must_equal 100
end
it "should not add the numbers higher than 1000" do
@sc.add("1,1,1\n1001").must_equal 3
end
it "should not allow the adding of negative numbers" do
lambda{ @sc.add("-1,-2,1") }.must_raise Exception
end
end
end

0 comments on commit 8be61d2

Please sign in to comment.