-
-
-
-
-
-
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..565fa8c
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,6 @@
+language: node_js
+node_js:
+ - "9"
+
+script:
+ - npm test
\ No newline at end of file
diff --git a/README.md b/README.md
index 5ce05db..0722582 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,7 @@
# data-structures-and-algorithms
+* [travis](https://www.travis-ci.com/MeStock/data-structures-and-algorithms)
+
Overview
This repo is a place to organize completed code challenges. Within the code challenges folder, you can find examples of different data structure and algorithm problems with their optimzed solutions.
@@ -218,3 +220,61 @@ Add in some conditionals for edge cases:
## Solution

+# Reverse an Array
+The reverse array function will take in an array as a parameter and return the elements of the array in reverser order.
+
+## Challenge
+Modify array in place
+
+## Approach & Efficiency
+I knew that I needed some sort of looping mechanism, so I started by visualizing the input and output of the array.
+ I: [1,2,3,4,5]
+ O: [5,4,3,2,1]
+Keeping track of the front index and back index and making swaps was the optimal solution.
+
+LOOP 1:
+[5,2,3,4,1]
+
+LOOP 2:
+[5,4,3,2,1]
+
+LOOP 3: reached the middle of the array so return the current state of the array.
+
+The time complexity for this is O(n) where n is half the length of the list and space complexity is O(1) because we are modifying in place.
+You can also solve this problem using built in array methods (reverse, push, pop) or recursively but the space/time complexities are not as efficient.
+
+## Solution
+
+
+# Find Sum of Integers
+Given an array and key, find the first pair of values within the array that add up and equal the key.
+
+## Challenge
+Modify array in place
+
+## Approach & Efficiency
+I used a hashmap to implement this search. Add all the values to a hashmap. Iterate through array, calculate the difference between each index of the array and the key. Use the hashmap to check if the difference exists within the map.
+
+Time complexity: O(n) where n is the length of the array
+Space complexity: O(n) where n is the length of the array
+
+The brure force method for this problem is to check every single pair within the array using nesed for loops. This would result in time complexity of O(n^2) and space complexity of O(1). Depending on individual cases, you would consider this case to save space.
+
+## Solution
+
+
+# Hashtables
+We mob programmed this challenge. Group members: Melissa Stock, Bonnie Wang, Jagdeep Singh, Rebecca Peterson, Joe Jemmely
+Implement a hashtable with the following built in methods : add(key, value), get(key), contains(key), and hash(key);
+
+## Challenge
+* add(key, value) returns the value that was just added
+* get(key) returns the value associated with the key
+* contains(key) returns true/false if the hashtable contains a value with the associated key
+* hash(key) returns an index associated with the unique hashed key
+
+## Approach & Efficiency
+* add(key, value) Time: O(L) where L is the length of the string Space: O(1) *if you ignore the hashing Time: O(1)
+* get(key) Time: O(L) where L is the length of the string Space: O(1) *if you ignore the hashing Time: O(1)
+* contains(key) Time: O(L) where L is the length of the string Space: O(1) *if you ignore the hashing Time: O(1)
+* hash(key) Time: O(L) where L is the length of the string Space: O(1)
\ No newline at end of file
diff --git a/__tests__/append-insert-before-after.test.js b/__tests__/append-insert-before-after.test.js
index b4b355d..d28ae1c 100644
--- a/__tests__/append-insert-before-after.test.js
+++ b/__tests__/append-insert-before-after.test.js
@@ -10,35 +10,35 @@ describe('Linked list', () => {
const test = new LinkedList();
expect(test.append('test')).toEqual(expect.objectContaining(test));
});
- xit('should properly insert before the first node of the list', () => {
- const test = new LinkedList();
- test.append('head');
- test.append('first node');
- test.append('second node');
- test.insertBefore('head','inserted before node');
- expect(test.value).toBe('inserted before node');
- });
- xit('should properly insert before i in the middle of the list', () => {
- const test = new LinkedList();
- test.append('head');
- test.append('first node');
- test.append('second node');
- test.insertBefore('first node','inserted node');
- expect(test.next.value).toEqual('inserted node');
- });
- xit('should properly insert after the last node of the list', () => {
- const test = new LinkedList();
- test.append('head');
- test.append('first node');
- test.insertAfter('first node', 'inserted node');
- expect(test.next.next.value).toEqual('inserted node');
- });
- xit('should properly insert in the middle of the list', () => {
- const test = new LinkedList();
- test.append('head');
- test.append('first node');
- test.append('second node');
- test.insertAfter('first node', 'inserted node');
- expect(test.next.next.value).toEqual('inserted node');
- });
-});
\ No newline at end of file
+ // xit('should properly insert before the first node of the list', () => {
+ // const test = new LinkedList();
+ // test.append('head');
+ // test.append('first node');
+ // test.append('second node');
+ // test.insertBefore('head','inserted before node');
+ // expect(test.value).toBe('inserted before node');
+ // });
+ // xit('should properly insert before i in the middle of the list', () => {
+ // const test = new LinkedList();
+ // test.append('head');
+ // test.append('first node');
+ // test.append('second node');
+ // test.insertBefore('first node','inserted node');
+ // expect(test.next.value).toEqual('inserted node');
+ // });
+ // xit('should properly insert after the last node of the list', () => {
+ // const test = new LinkedList();
+ // test.append('head');
+ // test.append('first node');
+ // test.insertAfter('first node', 'inserted node');
+ // expect(test.next.next.value).toEqual('inserted node');
+ // });
+ // xit('should properly insert in the middle of the list', () => {
+ // const test = new LinkedList();
+ // test.append('head');
+ // test.append('first node');
+ // test.append('second node');
+ // test.insertAfter('first node', 'inserted node');
+ // expect(test.next.next.value).toEqual('inserted node');
+ // });
+});
diff --git a/__tests__/array-reverse.test.js b/__tests__/array-reverse.test.js
new file mode 100644
index 0000000..43f0393
--- /dev/null
+++ b/__tests__/array-reverse.test.js
@@ -0,0 +1,31 @@
+'use strict';
+
+const arrayReverse1 = require('../code-challenges/array-reverse/array-reverse.js').reverseArray;
+const arrayReverse2 = require('../code-challenges/array-reverse/array-reverse.js').stretchGoal;
+const arrayReverse3 = require('../code-challenges/array-reverse/more-array-reverse.js');
+const reversedTest = ['d', 'c', 'b', 'a'];
+
+
+describe('Array Reverse', () => {
+ it('should reverse an array with one element', () => {
+ const test = ['a'];
+ expect(arrayReverse1(test)).toEqual(['a']);
+ expect(arrayReverse2(test)).toEqual(['a']);
+ expect(arrayReverse3(test)).toEqual(['a']);
+ });
+
+ it('should reverse any array of any size', () => {
+ const test1 = ['a', 'b', 'c', 'd'];
+ const test2 = ['a', 'b', 'c', 'd'];
+ const test3 = ['a', 'b', 'c', 'd'];
+ expect(arrayReverse1(test1)).toEqual(reversedTest);
+ expect(arrayReverse2(test2)).toEqual(reversedTest);
+ expect(arrayReverse3(test3)).toEqual(reversedTest);
+ });
+
+ it('should return null if no array is given', () => {
+ expect(arrayReverse1()).toBeNull();
+ expect(arrayReverse2()).toBeNull();
+ expect(arrayReverse3()).toBeNull();
+ });
+});
diff --git a/__tests__/findSumOfInts.test.js b/__tests__/findSumOfInts.test.js
new file mode 100644
index 0000000..c06a452
--- /dev/null
+++ b/__tests__/findSumOfInts.test.js
@@ -0,0 +1,22 @@
+'use strict';
+
+const findSumOfInts = require('../code-challenges/findSumOfInts/findSumOfInts.js');
+
+describe('find sum of integers', () => {
+ it('should find 2 numbers inside an array that add up to the key', () => {
+ const test = [1,4,8,3,7,2,0,-1];
+ expect(findSumOfInts(test, 11)).toEqual([4,7]);
+ });
+
+ it('should return null if inputs are not valid', () => {
+ expect(findSumOfInts()).toBeNull();
+ expect(findSumOfInts(1,2)).toBeNull();
+ expect(findSumOfInts([1,2,3], 'not a number')).toBeNull();
+ expect(findSumOfInts([], 4)).toBeNull();
+ });
+
+ it('should find the first pair that add up to the key', () => {
+ const test = [1,2,4,-1];
+ expect(findSumOfInts(test, 3)).toEqual([1,2]);
+ });
+});
diff --git a/__tests__/hashTables.test.js b/__tests__/hashTables.test.js
new file mode 100644
index 0000000..7c3b38a
--- /dev/null
+++ b/__tests__/hashTables.test.js
@@ -0,0 +1,53 @@
+'use strict';
+
+/*
+
+Write tests to prove the following functionality:
+
+Adding a key/value to your hashtable results in the value being in the data structure
+Retrieving based on a key returns the value stored
+Successfully returns null for a key that does not exist in the hashtable
+Successfully handle a collision within the hashtable
+Successfully retrieve a value from a bucket within the hashtable that has a collision
+Successfully hash a key to an in-range value
+
+*/
+
+const HashTable = require('../code-challenges/hashtables/hashtables.js');
+
+describe('Hash Tables', () => {
+ it('should add a key/value', () => {
+ const test = new HashTable();
+ expect(test.add('key', 'value')).toEqual('value');
+ });
+
+ it('should return the value associated with the key', () => {
+ const test = new HashTable();
+ test.add('key', 'value');
+ expect(test.get('key')).toEqual('value');
+ });
+
+ it('successfully return null for a key that does not exist in the table', () => {
+ const test = new HashTable();
+ test.add('key', 'value');
+ expect(test.get('not a key')).toBeNull();
+ });
+
+ it('successfully handle a collision within the hashtable', () => {
+ const test = new HashTable();
+ test.add('key', 'value');
+ expect(test.data[61].nextkey = 'next value').toEqual('next value');
+ });
+
+ it('successfully retrieves a value from a bucket within the hashtable that has a collision', () => {
+ const test = new HashTable();
+ test.add('key', 'value');
+ test.data[61].nextkey = 'next value';
+ expect(test.get('key')).toEqual('value');
+ });
+
+ it('successfully hash a key to an in-range value', () => {
+ const test = new HashTable();
+ expect(test.hash('key')).toEqual(61);
+ });
+});
diff --git a/assets/findSumOfInts.jpg b/assets/findSumOfInts.jpg
new file mode 100644
index 0000000..037e4de
Binary files /dev/null and b/assets/findSumOfInts.jpg differ
diff --git a/assets/more-array-reverse.jpg b/assets/more-array-reverse.jpg
new file mode 100644
index 0000000..35046e0
Binary files /dev/null and b/assets/more-array-reverse.jpg differ
diff --git a/code-challenges/array-reverse/array-reverse.js b/code-challenges/array-reverse/array-reverse.js
index e42dc16..08b6f0d 100644
--- a/code-challenges/array-reverse/array-reverse.js
+++ b/code-challenges/array-reverse/array-reverse.js
@@ -1,6 +1,8 @@
// Write a function called reverseArray which takes an array as an argument. Without utilizing any of the built-in methods available to your language, return an array with elements in reversed order.
function reverseArray(arr){
+ if(!arr) return null;
+ if(arr.length === 1) return arr;
let result = [];
for(let i = arr.length - 1; i >= 0; i--){
result.push(arr[i]);
@@ -8,12 +10,13 @@ function reverseArray(arr){
return result;
}
-console.log(reverseArray([1,2,3,4,5]));
// STRETCH GOAL
// Once you’ve achieved a working solution, implement the same feature with a different methodology. (Hint: what different techniques do you have when working with arrays? Recursion, loops, indexes, modifying the array input directly…)
function stretchGoal(arr){
+ if(!arr) return null;
+ if(arr.length === 1) return arr;
let result = [];
let length = arr.length;
for(let i = 0; i < length; i++){
@@ -23,4 +26,5 @@ function stretchGoal(arr){
return result;
}
-console.log(stretchGoal([1,2,3,4,5]));
+module.exports = {reverseArray, stretchGoal};
+
diff --git a/code-challenges/array-reverse/more-array-reverse.js b/code-challenges/array-reverse/more-array-reverse.js
new file mode 100644
index 0000000..c3d8ed6
--- /dev/null
+++ b/code-challenges/array-reverse/more-array-reverse.js
@@ -0,0 +1,17 @@
+'use strict';
+
+function reverseAnArray(array){
+ if(!array) return null;
+ if(array.length === 1) return array;
+ const middleOfArray = Math.floor(array.length / 2);
+ for(let i = 0; i < middleOfArray; i++){
+ let front = array[i];
+ let back = array[(array.length - 1) - i];
+
+ array[(array.length - 1) - i] = front;
+ array[i] = back;
+ }
+ return array;
+}
+
+module.exports = reverseAnArray;
diff --git a/code-challenges/findSumOfInts/findSumOfInts.js b/code-challenges/findSumOfInts/findSumOfInts.js
new file mode 100644
index 0000000..69e3970
--- /dev/null
+++ b/code-challenges/findSumOfInts/findSumOfInts.js
@@ -0,0 +1,24 @@
+'use strict';
+
+/*
+Problem Domain: Given an array of integers and a value, find a pair of integers in the array that add to that value.
+
+*/
+
+function findSumOfInts(array, key){
+ if(!array || !key) return null;
+ if(typeof key !== 'number' || typeof array !== 'object') return null;
+ if(array.length < 2) return null;
+ const hashMap = new Map();
+ for(let i = 0; i < array.length; i++){
+ hashMap.set(array[i]);
+ }
+ for(let j = 0; j < array.length; j++){
+ let difference = key - array[j];
+ if(hashMap.has(difference)){
+ return [array[j], difference];
+ }
+ }
+}
+
+module.exports = findSumOfInts;
diff --git a/code-challenges/hashtables/hashtables.js b/code-challenges/hashtables/hashtables.js
new file mode 100644
index 0000000..eeedeac
--- /dev/null
+++ b/code-challenges/hashtables/hashtables.js
@@ -0,0 +1,56 @@
+'use strict';
+
+/*
+
+add: takes in both the key and value. This method should hash the key, and add the key and value pair to the table, handling collisions as needed.
+get: takes in the key and returns the value from the table.
+contains: takes in the key and returns a boolean, indicating if the key exists in the table already.
+hash: takes in an arbitrary key and returns an index in the collection.
+
+*/
+
+class HashTable{
+ constructor(length){
+ this.LENGTH = length || 100;
+ this.data = new Array(this.LENGTH);
+ for(let i = 0; i < this.LENGTH; i++){
+ this.data[i] = {};
+ }
+ }
+
+ _stringSum(key){
+ return key.split('').reduce((accumulator, current) => {
+ current = current.charCodeAt(0);
+ return accumulator += current;
+ },0);
+ }
+
+ hash(key){
+ if(typeof key !== 'string' && typeof key !== 'number') return null;
+
+ let convertedKey;
+ if(typeof key === 'string'){
+ convertedKey = this._stringSum(key);
+ }else{
+ convertedKey = key;
+ }
+ return convertedKey * 599 % (this.LENGTH - 1);
+ }
+
+ get(key){
+ let index = this.hash(key);
+ return this.data[index][key] ? this.data[index][key] : null;
+ }
+
+ contains(key){
+ let index = this.hash(key);
+ return !!this.data[index][key];
+ }
+
+ add(key, value){
+ const index = this.hash(key);
+ return Object.assign(this.data[index], {[key]: value})[key];
+ }
+}
+
+module.exports = HashTable;