diff --git a/SpecRunner.html b/SpecRunner.html
index 5a18ca964..81b5cea16 100644
--- a/SpecRunner.html
+++ b/SpecRunner.html
@@ -29,7 +29,7 @@
});
-
+
diff --git a/spec/part1.js b/spec/part1.js
index f2ec9ba33..72360c485 100755
--- a/spec/part1.js
+++ b/spec/part1.js
@@ -84,7 +84,7 @@
- xdescribe('3. Sum Integers in Array', function() {
+ describe('3. Sum Integers in Array', function() {
it('should return a number', function() {
expect(typeof(arraySum([[1],[2,3],[[4]],5,6]))).to.eql('number');
@@ -402,7 +402,7 @@
- xdescribe('11. Modulo', function() {
+ describe('11. Modulo', function() {
it('should return a number', function() {
expect(typeof(modulo(5,2))).to.equal('number');
@@ -476,7 +476,7 @@
- xdescribe('13. Divide', function() {
+ describe('13. Divide', function() {
it('should return a number', function() {
expect(typeof(divide(5,2))).to.equal('number');
@@ -512,7 +512,7 @@
- xdescribe('14. Greatest Common Divisor', function() {
+ describe('14. Greatest Common Divisor', function() {
it('should return a number', function() {
expect(typeof(gcd(4,36))).to.equal('number');
@@ -726,7 +726,7 @@
- xdescribe('21. Count key in object', function() {
+ describe('21. Count key in object', function() {
var input = {'e': {'x':'y'}, 't':{'r': {'e':'r'}, 'p': {'y':'r'}},'y':'e'};
it('should return a number', function() {
@@ -756,7 +756,7 @@
- xdescribe('22. Count value in object', function() {
+ describe('22. Count value in object', function() {
var input = {'e': {'x':'y'}, 't':{'r': {'e':'r'}, 'p': {'y':'r'}},'y':'e'};
it('should return a number', function() {
@@ -786,7 +786,7 @@
- xdescribe('23. Replace keys in object', function() {
+ describe('23. Replace keys in object', function() {
var tallyKeys = function(obj) {
var count = 0;
@@ -850,7 +850,7 @@
});
- xdescribe('24. First n Fibonacci', function() {
+ describe('24. First n Fibonacci', function() {
it('should return an array', function() {
expect(Array.isArray(fibonacci(5))).to.equal(true);
@@ -961,7 +961,7 @@
- xdescribe('28. Sum even numbers in nested objects', function() {
+ describe('28. Sum even numbers in nested objects', function() {
var obj = {
a: 2,
b: {b: 2, bb: {b: 3, bb: {b: 2}}},
@@ -990,7 +990,7 @@
- xdescribe('29. Flatten nested arrays', function() {
+ describe('29. Flatten nested arrays', function() {
it('should return an array', function() {
expect(Array.isArray(flatten([1,[2],[3,[[4]]],5]))).to.equal(true);
@@ -1073,7 +1073,7 @@
- xdescribe('32. Augment each element in nested arrays', function() {
+ describe('32. Augment each element in nested arrays', function() {
it('should return an array', function() {
expect(Array.isArray(augmentElements([[],[3],[7]], 5))).to.equal(true);
@@ -1147,7 +1147,7 @@
- xdescribe('35. Convert numbers to text', function() {
+ describe('35. Convert numbers to text', function() {
it('should return a string', function() {
expect(typeof(numToText("I have 5 dogs and 6 ponies"))).to.equal('string');
diff --git a/src/recursion.js b/src/recursion.js
index e92a8866c..b9f38f1c2 100644
--- a/src/recursion.js
+++ b/src/recursion.js
@@ -5,31 +5,99 @@
// Example: 5! = 5 x 4 x 3 x 2 x 1 = 120
// factorial(5); // 120
var factorial = function(n) {
+ if(n < 0){
+ return null;
+ }if(n === 0){
+ return 1;
+ }
+ return n * factorial(n-1)
};
// 2. Compute the sum of an array of integers.
// Example: sum([1, 2, 3, 4, 5, 6]); // 21
var sum = function(array) {
+
+ if(array.length === 0){
+ return 0;
+ }
+
+ return array[0] + sum(array.slice(1))
};
// 3. Sum all numbers in an array containing nested arrays.
// Example: arraySum([1,[2,3],[[4]],5]); // 15
var arraySum = function(array) {
+ let sum =0;
+if(array.length === 0){
+ return sum;
+}
+for(var i = 0; i 0 ){
+ return (n-1) + sumBelow(n-1)
+ }
+
};
// 6. Get the integers in range (x, y).
// Example: range(2, 9); // [3, 4, 5, 6, 7, 8]
var range = function(x, y) {
+ let retval = [];
+ if(x === y-1){
+ return retval;
+ } if( x === y +1 ){
+ return retval;
+ }
+ if(x === y ){
+ return retval;
+ }
+ if(x < y){
+
+ retval.push(x+1);
+ return retval.concat(range(x+1,y))
+ }
+ if( x > y){
+ retval.push(x -1);
+ return retval.concat(range(x-1,y))
+ }
+
};
// 7. Compute the exponent of a number.
@@ -38,6 +106,15 @@ var range = function(x, y) {
// Example: exponent(4,3); // 64
// https://www.khanacademy.org/computing/computer-science/algorithms/recursive-algorithms/a/computing-powers-of-a-number
var exponent = function(base, exp) {
+ if(exp===0){
+ return 1;
+ } //base case
+ if(exp < 0) {
+ return exponent(base,exp+1)/base;
+ }
+ return base * exponent(base, exp-1);
+
+
};
// 8. Determine if a number is a power of two.
@@ -45,15 +122,30 @@ var exponent = function(base, exp) {
// powerOfTwo(16); // true
// powerOfTwo(10); // false
var powerOfTwo = function(n) {
+ return n == 1 ? true : (n < 1 ? false : powerOfTwo(n/2));
};
// 9. Write a function that accepts a string a reverses it.
var reverse = function(string) {
+ if(string.length ===0){
+ return string;
+ }
+ return reverse(string.substring(1)) + string[0]
};
// 10. Write a function that determines if a string is a palindrome.
var palindrome = function(string) {
-};
+ string = string.toLowerCase().trim();
+ if(string.length< 2){
+ return true;
+ }
+ if(string[0] === string[string.length-1]){
+ // debugger;
+ return palindrome(string.substring(1,string.length-1));
+ } else{
+ return false;
+ }
+ };
// 11. Write a function that returns the remainder of x divided by y without using the
// modulo (%) operator.
@@ -61,16 +153,54 @@ var palindrome = function(string) {
// modulo(17,5) // 2
// modulo(22,6) // 4
var modulo = function(x, y) {
+ if (y === 0) {
+ return NaN;
+ }
+ if (x < 0) { return -modulo(-x, y); }
+
+ if (y < 0) { return modulo( x, -y); }
+
+ if (x < y) { return x; }
+
+ return modulo(x - y, y);
};
// 12. Write a function that multiplies two numbers without using the * operator or
// JavaScript's Math object.
var multiply = function(x, y) {
+ if(y===0){
+ return 0;
+ }
+ if(y>0){
+ return x + multiply(x,y-1);
+ }
+ if(y<0){
+ return multiply(-x,-y);
+ }
};
// 13. Write a function that divides two numbers without using the / operator or
// JavaScript's Math object.
var divide = function(x, y) {
+ if (x === 0 && y === 0) {
+ return NaN;
+ }
+ if (x===0) {
+ return 0;
+ }
+ if (y===1) {
+ return x;
+ }
+ if (x < y) {
+ return 0;
+ }
+ if (x+y < 0) {
+ return 0;
+ }
+ if (x-y < y) {
+ return 1;
+ }
+ return 1 + divide(x-y, y);
};
// 14. Find the greatest common divisor (gcd) of two positive numbers. The GCD of two
@@ -79,6 +209,16 @@ var divide = function(x, y) {
// http://www.cse.wustl.edu/~kjg/cse131/Notes/Recursion/recursion.html
// https://www.khanacademy.org/computing/computer-science/cryptography/modarithmetic/a/the-euclidean-algorithm
var gcd = function(x, y) {
+ if(x<0||y<0){
+ return null
+ }
+ if ( ! y) {
+ return x;
+ }
+ if(x=== -x|| y === -y){
+ return null;
+ }
+ return gcd(y, x % y);
};
// 15. Write a function that compares each character of two strings and returns true if
@@ -87,32 +227,80 @@ var gcd = function(x, y) {
// compareStr('', '') // true
// compareStr('tomato', 'tomato') // true
var compareStr = function(str1, str2) {
+ if(str1[0] !== str2[0]){
+ return false;
+ }
+ if( str1.length === 0 && str2.length ===0){
+ return true;
+ }
+
+
+ return compareStr(str1.substring(1),str2.substring(1))
+
};
// 16. Write a function that accepts a string and creates an array where each letter
// occupies an index of the array.
var createArray = function(str){
+ let retval = [];
+ if(str.length === 0 ){
+ return retval;
+ }
+ if(str[0]){
+ retval.push(str[0])
+ }
+ return retval.concat(createArray(str.substring(1)))
};
// 17. Reverse the order of an array
var reverseArr = function (array) {
+ let retval =[];
+ if(array.length === 0){
+ return retval;
+ }
+ if(array[array.length-1]){
+ retval.push(array[array.length-1])
+ }
+ return retval.concat(reverseArr(array.slice(0,-1)))
};
// 18. Create a new array with a given value and length.
// buildList(0,5) // [0,0,0,0,0]
// buildList(7,3) // [7,7,7]
var buildList = function(value, length) {
+ let retval = [];
+ if(length === 0){
+ return retval;
+ }
+ retval.push(value)
+ return retval.concat(buildList(value,length-1))
};
// 19. Count the occurence of a value inside a list.
// countOccurrence([2,7,4,4,1,4], 4) // 3
// countOccurrence([2,'banana',4,4,1,'banana'], 'banana') // 2
var countOccurrence = function(array, value) {
+ let count = 0;
+ if(array.length ===0 ){
+ return count;
+ }
+ if(array[0]=== value){
+ count++
+ }
+ return count + countOccurrence(array.slice(1),value)
};
// 20. Write a recursive version of map.
// rMap([1,2,3], timesTwo); // [2,4,6]
var rMap = function(array, callback) {
+ let retval = [];
+ if(array.length === 0){
+ return retval;
+ }
+ if(array[0]){
+ retval.push(callback(array[0]))
+ }
+ return retval.concat(rMap(array.slice(1),callback))
};
// 21. Write a function that counts the number of times a key occurs in an object.
@@ -120,6 +308,23 @@ var rMap = function(array, callback) {
// countKeysInObj(testobj, 'r') // 1
// countKeysInObj(testobj, 'e') // 2
var countKeysInObj = function(obj, key) {
+ let count = 0;
+ for(var keys in obj){
+ if(keys === key){
+ count += 1;
+ }
+ if(typeof obj[keys] === "object"){
+ count += countKeysInObj(obj[keys],key)
+
+ }
+
+
+
+
+
+ }
+ return count;
+
};
// 22. Write a function that counts the number of times a value occurs in an object.
@@ -127,11 +332,31 @@ var countKeysInObj = function(obj, key) {
// countValuesInObj(testobj, 'r') // 2
// countValuesInObj(testobj, 'e') // 1
var countValuesInObj = function(obj, value) {
+ let count = 0;
+ for(var keys in obj){
+ if(obj[keys] === value){
+ count += 1;
+ }
+ if(typeof obj[keys] === "object"){
+ count += countValuesInObj(obj[keys],value)
+ }
+ }
+ return count;
+
};
// 23. Find all keys in an object (and nested objects) by a provided name and rename
// them to a provided new name while preserving the value stored at that key.
var replaceKeysInObj = function(obj, key, newKey) {
+ for(var keys in obj){
+ if(keys === key){
+ obj[newKey] = obj[key];
+ delete obj[keys]
+ } if( typeof obj[keys]=== "object"){
+ replaceKeysInObj(obj[keys],key,newKey)
+ }
+ }
+ return obj;
};
// 24. Get the first n Fibonacci numbers. In the Fibonacci Sequence, each subsequent
@@ -140,6 +365,22 @@ var replaceKeysInObj = function(obj, key, newKey) {
// fibonacci(5); // [0, 1, 1, 2, 3, 5]
// Note: The 0 is not counted.
var fibonacci = function(n) {
+
+ if( n < 1){
+ return null;
+ }
+ if( n === 1){
+ return [0,1];
+
+ }else{
+ var fib = fibonacci(n-1)
+
+ fib.push(fib[fib.length-1]+fib[fib.length-2])
+ return fib;
+ }
+
+
+
};
// 25. Return the Fibonacci number located at index n of the Fibonacci sequence.
@@ -148,17 +389,43 @@ var fibonacci = function(n) {
// nthFibo(7); // 13
// nthFibo(3); // 2
var nthFibo = function(n) {
+ if (n < 0){
+ return null;
+
+ }else if(n === 0){
+ return 0;
+ }else if(n === 1 || n === 2){
+ return 1;
+ }else{
+ return nthFibo(n - 1) + nthFibo(n - 2);
+ }
};
// 26. Given an array of words, return a new array containing each word capitalized.
// var words = ['i', 'am', 'learning', 'recursion'];
// capitalizedWords(words); // ['I', 'AM', 'LEARNING', 'RECURSION']
var capitalizeWords = function(input) {
+ let retval = [];
+ if (input.length ===0){
+ return retval;
+ }
+ if(input[0]){
+ retval.push(input[0].toUpperCase())
+ }
+ return retval.concat(capitalizeWords(input.slice(1)))
};
// 27. Given an array of strings, capitalize the first letter of each index.
// capitalizeFirst(['car', 'poop', 'banana']); // ['Car', 'Poop', 'Banana']
var capitalizeFirst = function(array) {
+ let retval = [];
+ if(array.length === 0){
+ return retval;
+ }
+ if(array[0]){
+ retval.push(array[0][0].toUpperCase() + array[0].slice(1))
+ }
+ return retval.concat(capitalizeFirst(array.slice(1)))
};
// 28. Return the sum of all even numbers in an object containing nested objects.
@@ -171,16 +438,49 @@ var capitalizeFirst = function(array) {
// };
// nestedEvenSum(obj1); // 10
var nestedEvenSum = function(obj) {
+ let count = 0;
+ for(var key in obj){
+ if( obj[key]%2 === 0){
+ count += obj[key]
+ }else if(typeof obj[key] === "object"){
+ count += nestedEvenSum(obj[key])
+ }
+ }
+ return count;
};
// 29. Flatten an array containing nested arrays.
// Example: flatten([1,[2],[3,[[4]]],5]); // [1,2,3,4,5]
var flatten = function(arrays) {
+ let retval = [];
+
+ console.log(retval,arrays)
+ if(!Array.isArray(arrays)){
+ return arrays
+ }
+ if(Array.isArray(arrays)){
+ for(var i = 0; i < arrays.length; i++){
+ retval = retval.concat(flatten(arrays[i]))
+ }
+ return retval;
+ }
};
// 30. Given a string, return an object containing tallies of each letter.
// letterTally('potato'); // {'p':1, 'o':2, 't':2, 'a':1}
-var letterTally = function(str, obj) {
+var letterTally = function(str, obj ={}) {
+
+ if(str.length === 0){
+ console.log(obj)
+ return obj
+ }
+ if(!obj[str[0]]){
+ obj[str[0]] = 1
+ }else{
+ obj[str[0]]++
+ }
+ return letterTally(str.substring(1),obj)
+
};
// 31. Eliminate consecutive duplicates in a list. If the list contains repeated
@@ -189,18 +489,43 @@ var letterTally = function(str, obj) {
// Example: compress([1, 2, 2, 3, 4, 4, 5, 5, 5]) // [1, 2, 3, 4, 5]
// Example: compress([1, 2, 2, 3, 4, 4, 2, 5, 5, 5, 4, 4]) // [1, 2, 3, 4, 2, 5, 4]
var compress = function(list) {
+ let retval = [];
+ if (list.length === 0 ){
+ return retval;
+ }
+ if(list[0] && list[0]!== list[1]){
+ retval.push(list[0])
+ }
+ return retval.concat(compress(list.slice(1)))
};
// 32. Augument every element in a list with a new value where each element is an array
// itself.
// Example: augmentElements([[],[3],[7]], 5); // [[5],[3,5],[7,5]]
var augmentElements = function(array, aug) {
+ let retval = [];
+if (array.length === 0){
+ return retval;
+}
+ array[0].push(aug)
+ retval.push(array[0])
+return retval.concat(augmentElements(array.slice(1),aug))
};
// 33. Reduce a series of zeroes to a single 0.
// minimizeZeroes([2,0,0,0,1,4]) // [2,0,1,4]
// minimizeZeroes([2,0,0,0,1,0,0,4]) // [2,0,1,0,4]
var minimizeZeroes = function(array) {
+ retval = [];
+ if(array.length === 0){
+ return retval;
+ }
+
+ if(array[0]||array[0] === 0&& array[1]!==0){
+
+ retval.push(array[0])
+ }
+ return retval.concat(minimizeZeroes(array.slice(1)))
};
// 34. Alternate the numbers in an array between positive and negative regardless of
@@ -208,12 +533,38 @@ var minimizeZeroes = function(array) {
// alternateSign([2,7,8,3,1,4]) // [2,-7,8,-3,1,-4]
// alternateSign([-2,-7,8,3,-1,4]) // [2,-7,8,-3,1,-4]
var alternateSign = function(array) {
+ let retval =[];
+ if(array.length === 0){
+ return retval;
+ }
+ if(array.length % 2 ==0){
+ retval.push(Math.abs(array[0]))
+ }else{
+ retval.push(-Math.abs(array[0]))
+ }
+ return retval.concat(alternateSign(array.slice(1)))
};
// 35. Given a string, return a string with digits converted to their word equivalent.
// Assume all numbers are single digits (less than 10).
// numToText("I have 5 dogs and 6 ponies"); // "I have five dogs and six ponies"
var numToText = function(str) {
+ let newString;
+ let numToString = ['zero','one','two','three','four','five','six','seven','eight','nine'];
+
+ if(str.length === 0){
+ // console.log(str,'here');
+ return str
+ }
+ //test and see if the any part of the string can be turned into a number
+ if(Number(str[0])){
+
+
+
+ return numToString[Number(str[0])] + numToText(str.slice(1,str.length))
+ } else{
+ return str[0] + numToText(str.slice(1,str.length))
+ }
};
// *** EXTRA CREDIT ***