From 3effffb1057bc3e34672fed5c8310ee5989d7444 Mon Sep 17 00:00:00 2001 From: "Andre P. Oliveira" Date: Wed, 4 Jun 2014 14:27:20 -0400 Subject: [PATCH 1/2] Add Set data structure --- data_structures/set.js | 115 ++++++++++++++++++++++++++++++++++++ main.js | 3 +- test/data_structures/set.js | 112 +++++++++++++++++++++++++++++++++++ 3 files changed, 229 insertions(+), 1 deletion(-) create mode 100644 data_structures/set.js create mode 100644 test/data_structures/set.js diff --git a/data_structures/set.js b/data_structures/set.js new file mode 100644 index 0000000..0c824ec --- /dev/null +++ b/data_structures/set.js @@ -0,0 +1,115 @@ +/** + * Copyright (C) 2014 Andre Oliveira + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"], to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +'use strict'; + +/** + * Typical representation of a mathematical set + * No restriction on element types + * i.e. set.add(1,'a', "b", { "foo" : "bar" }) + */ +var Set = function() { + this.elts = []; + + var toAdd = arguments || []; + for(var i = 0; i < toAdd.length; i++) { + this.add(toAdd[i]); + } +} + +Set.prototype.add = function() { + for(var i = 0; i < arguments.length; i++) { + if(!this.contains(arguments[i])) { + this.elts.push(arguments[i]); + } + } + return this; +} + +Set.prototype.remove = function() { + for(var i = 0; i < arguments.length; i++) { + if(this.contains(arguments[i])) + this.elts.splice(this.elts.indexOf(arguments[i]),1); + } + return this; +} + +Set.prototype.contains = function(elt) { + for(var i = 0; i < this.elts.length; i++) { + if(this.elts[i] === elt) { + return true; + } + } + return false; +} + +Set.prototype.intersect = function(other) { + var newSet = new Set(); + for(var i = 0; i < this.elts.length; i++){ + if(other.contains(this.elts[i])) + newSet.add(this.elts[i]); + } + return newSet; +} + +Set.prototype.union = function(other) { + var newSet = new Set(); + + for(var i = 0; i < this.elts.length; i++) + newSet.add(this.elts[i]); + for(var i = 0; i < other.elts.length; i++) + newSet.add(other.elts[i]); + + return newSet; +} + +Set.prototype.subset = function(other) { + for(var i = 0; i < this.elts.length; i++) { + if(!other.contains(this.elts[i])) { + return false; + } + } + return true; +} + +Set.prototype.minus = function(other) { + var newSet = new Set(); + for(var i = 0; i < this.elts.length; i++){ + if(!other.contains(this.elts[i])){ + newSet.add(this.elts[i]); + } + } + return newSet; +} + +Set.prototype.symDiff = function(other) { + return (this.minus(other)).union(other.minus(this)); +} + +Set.prototype.size = function() { + return this.elts.length; +} + +Set.prototype.equals = function(other) { + return this.subset(other) && other.subset(this); +} + +module.exports = Set; diff --git a/main.js b/main.js index 987862a..cdf5723 100644 --- a/main.js +++ b/main.js @@ -58,7 +58,8 @@ var lib = { LinkedList: require('./data_structures/linked_list'), PriorityQueue: require('./data_structures/priority_queue'), Queue: require('./data_structures/queue'), - Stack: require('./data_structures/stack') + Stack: require('./data_structures/stack'), + Set: require('./data_structures/set') } }; diff --git a/test/data_structures/set.js b/test/data_structures/set.js new file mode 100644 index 0000000..b324899 --- /dev/null +++ b/test/data_structures/set.js @@ -0,0 +1,112 @@ +/** + * Copyright (C) 2014 Andre Oliveira + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +'use strict'; + +var Set = require('../../data_structures/set'), + assert = require('assert'); + +describe('Set', function () { + it('should start empty', function () { + var s = new Set(); + assert.equal(s.size(), 0); + }); + + it('should add all initial arguments', function () { + var s = new Set(1,2,3); + assert.deepEqual(s.elts, [1,2,3]); + }); + + it('should add all arguments', function () { + var s = new Set(1,2,3); + s.add(4,5,6); + assert.deepEqual(s.elts, [1,2,3,4,5,6]); + }); + + it('should remove all arguments', function() { + var s = new Set(1,2,3); + s.remove(1,3); + assert.deepEqual(s.elts, [2]); + }); + + it('should do nothing if an element that doesn\'t exist is removed', function() { + var s = new Set(1,2,3); + s.remove(4); + assert.deepEqual(s.elts, [1,2,3]); + }); + + it('should only contain its elements', function() { + var s = new Set(1,2,3); + assert.equal(s.contains(1), true); + assert.equal(s.contains(4), false); + }); + + it('should check subsets', function() { + var s = new Set(); + var t = new Set(1,2,3); + assert.equal(s.subset(s), true); + assert.equal(s.subset(t), true); + assert.equal(t.subset(s), false); + assert.equal(t.subset(t), true); + }); + + it('should union', function() { + var s = new Set(1,2,3); + var t = new Set(3,4,5); + assert.deepEqual(s.union(t).elts,[1,2,3,4,5]); + }); + + it('should intersect', function() { + var s = new Set(1,2,3); + var t = new Set(3,4,5); + assert.deepEqual(s.intersect(t).elts,[3]); + }); + + it('should subtract other sets', function() { + var s = new Set(1,2,3); + var t = new Set(3,4,5); + assert.deepEqual(s.minus(t).elts,[1,2]); + assert.deepEqual(t.minus(s).elts,[4,5]); + }); + + it('should get symmetric difference', function() { + var s = new Set(1,2,3); + var t = new Set(3,4,5); + assert.deepEqual(s.symDiff(t).elts,[1,2,4,5]); + assert.deepEqual(t.symDiff(s).elts,[4,5,1,2]); + }); + + it('should check equality', function() { + var s = new Set(); + var t = new Set(); + assert.equal(s.equals(s), true); + assert.equal(s.equals(t), true); + assert.equal(t.equals(s), true); + s.add(1,2,3); + t.add(1,2,3); + assert.equal(s.equals(s), true); + assert.equal(s.equals(t), true); + t.remove(2,3); + assert.equal(s.equals(t), false); + }); +}); + + From d0ee8d687b532b89c92b1c7bc3a7958be048bf5e Mon Sep 17 00:00:00 2001 From: "Andre P. Oliveira" Date: Thu, 5 Jun 2014 09:53:12 -0400 Subject: [PATCH 2/2] Add minor fixes to pass build --- data_structures/set.js | 30 ++++++++++++++++-------------- test/data_structures/set.js | 2 +- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/data_structures/set.js b/data_structures/set.js index 0c824ec..949f932 100644 --- a/data_structures/set.js +++ b/data_structures/set.js @@ -33,7 +33,7 @@ var Set = function() { for(var i = 0; i < toAdd.length; i++) { this.add(toAdd[i]); } -} +}; Set.prototype.add = function() { for(var i = 0; i < arguments.length; i++) { @@ -42,7 +42,7 @@ Set.prototype.add = function() { } } return this; -} +}; Set.prototype.remove = function() { for(var i = 0; i < arguments.length; i++) { @@ -50,7 +50,7 @@ Set.prototype.remove = function() { this.elts.splice(this.elts.indexOf(arguments[i]),1); } return this; -} +}; Set.prototype.contains = function(elt) { for(var i = 0; i < this.elts.length; i++) { @@ -59,7 +59,7 @@ Set.prototype.contains = function(elt) { } } return false; -} +}; Set.prototype.intersect = function(other) { var newSet = new Set(); @@ -68,18 +68,20 @@ Set.prototype.intersect = function(other) { newSet.add(this.elts[i]); } return newSet; -} +}; Set.prototype.union = function(other) { var newSet = new Set(); - for(var i = 0; i < this.elts.length; i++) + for(var i = 0; i < this.elts.length; i++) { newSet.add(this.elts[i]); - for(var i = 0; i < other.elts.length; i++) - newSet.add(other.elts[i]); + } + for(var j = 0; j < other.elts.length; j++) { + newSet.add(other.elts[j]); + } return newSet; -} +}; Set.prototype.subset = function(other) { for(var i = 0; i < this.elts.length; i++) { @@ -88,7 +90,7 @@ Set.prototype.subset = function(other) { } } return true; -} +}; Set.prototype.minus = function(other) { var newSet = new Set(); @@ -98,18 +100,18 @@ Set.prototype.minus = function(other) { } } return newSet; -} +}; Set.prototype.symDiff = function(other) { return (this.minus(other)).union(other.minus(this)); -} +}; Set.prototype.size = function() { return this.elts.length; -} +}; Set.prototype.equals = function(other) { return this.subset(other) && other.subset(this); -} +}; module.exports = Set; diff --git a/test/data_structures/set.js b/test/data_structures/set.js index b324899..60b4aa6 100644 --- a/test/data_structures/set.js +++ b/test/data_structures/set.js @@ -47,7 +47,7 @@ describe('Set', function () { assert.deepEqual(s.elts, [2]); }); - it('should do nothing if an element that doesn\'t exist is removed', function() { + it('should do nothing xist is removed', function() { var s = new Set(1,2,3); s.remove(4); assert.deepEqual(s.elts, [1,2,3]);