diff --git a/.gitignore b/.gitignore index 07e6e47..5e52727 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /node_modules +package-lock.json diff --git a/src/index.js b/src/index.js index 47844e2..02fe289 100644 --- a/src/index.js +++ b/src/index.js @@ -2,4 +2,189 @@ function add(a, b){ return a + b; } -exports.add = add; +function longestString(stringsArray) { + let seenLengths = {}; + + let lengths = stringsArray.map(string => { + seenLengths[string.length] + ? seenLengths[string.length] += 1 + : seenLengths[string.length] = 1; + return string.length; + }); + + let maxLength = Math.max(...lengths); + let maxLengthIndex = lengths.indexOf(maxLength); + + if (seenLengths[maxLength] > 1) return -1; + + return stringsArray[maxLengthIndex]; +} + +function l337 (inputString) { + //if (!inputString) throw new Error ('No input specified'); + + let dictionary = { + i : 1, + l : 1, + z : 2, + e : 3, + a : 4, + s : 5, + g : 6, + t : 7, + y : 7, + b : 8, + q : 9, + o : '0' + }; + + return inputString.split('').map(x => dictionary[x] || x ).join(''); +} + +function uniqueStrings (stringArray) { + return stringArray.reduce((acc,string)=>{ + if(acc.includes(string)) return acc + acc.push(string) + return acc + },[]); +} + +function Developer (name, languages) { + this.name = name; + this.languages = languages; +} + +Developer.prototype.learnLanguage = function (language) { + if (!this.languages.includes(language)) this.languages.push(language); +}; + +function Garden (plants) { + Object.assign(this,plants); +} + +Garden.prototype.plant = function (plants) { + Object.keys(plants).forEach( newPlant => { + this[newPlant] + ? this[newPlant] += plants[newPlant] + : this[newPlant] = plants[newPlant]; + }); +} + +Garden.prototype.harvest = function (plants) { + Object.keys(plants).forEach( harvesting => { + if(this[harvesting]){ + this[harvesting] -= plants[harvesting]; + if (this[harvesting]< 1) delete this[harvesting]; + } + }); +}; + +stringsConcat= function(inputArray){ + return inputArray.reduce((finalString, input)=>{ + if( typeof input == 'string' ) finalString.push(input); + return finalString; + },[]).join(' ') +} + +function negativeOnly (inputArray) { + return inputArray.reduce((output, input) => { + if (input < 0) output.push(input); + return output; + }, []); +} + +function camelise (inputString) { + let inputArray = inputString.split(' '); + + let firstWord = inputArray.shift(); + let outputString = inputArray.map((word) =>{ + return word.slice(0,1).toUpperCase() + word.slice(1); + }).join(''); + return firstWord.slice(0,1).toLowerCase() + firstWord.slice(1) + outputString; +} + +function merging (objectArray){ + return objectArray.sort((x,y)=>{ + return Object.keys(y).length - Object.keys(x).length + }).reduce((acc,obj)=>{ + acc = Object.assign(acc,obj); + return acc; + },{}) + +} + +function possibleValues(objectArray) { + return objectArray.reduce((acc, obj) => { + Object.keys(obj).forEach((objKey) => { + if (acc[objKey] && !acc[objKey].includes(obj[objKey])) { + acc[objKey].push(obj[objKey]); + } else if (!acc[objKey]) { + acc[objKey] = [ obj[objKey] ]; + } + }); + + return acc; + }, {}); +} + +function isPrime(n){ + if(n<2)return false; + + let q= Math.floor(Math.sqrt(n)); + + for(let i =2; i<= q ; i++){ + if(n%i===0) return false; + } + return true; +} + +function Walker (direction='N') { + if (direction.match(/^[NSEW]$/i)) { + this.direction = direction; + } else { + this.direction = 'N'; + console.log(`I don't understand ${direction}, defaulting to N`); + } + + this.coords = [0,0]; + this.pathTaken = [[0,0]]; +} + +Walker.prototype.walk = function (direction,steps){ + + direction= direction.toUpperCase(); + this.direction=direction; + + if(direction === 'N') { + this.coords[1] += steps; + }else if(direction === 'S') { + this.coords[1] -= steps; + } + else if(direction === 'E') { + this.coords[0] += steps; + } + else if(direction === 'W') { + this.coords[0] -= steps; + } + + this.pathTaken.push([...this.coords]) + +} + +Walker.prototype.pathTaken = function () { + return this.pathTaken; +} + +module.exports.add = add; +module.exports.longestString = longestString; +module.exports.l337 = l337; +module.exports.merging = merging +module.exports.uniqueStrings = uniqueStrings; +module.exports.Developer = Developer; +module.exports.Garden = Garden; +module.exports.stringsConcat = stringsConcat; +module.exports.negativeOnly = negativeOnly; +module.exports.camelise = camelise; +module.exports.possibleValues = possibleValues; +module.exports.isPrime= isPrime +module.exports.Walker = Walker; \ No newline at end of file diff --git a/test/index.test.js b/test/index.test.js index b1f6772..da58fbc 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -5,3 +5,212 @@ test('Addition', function(){ const result = functions.add(2, 3); expect(result).toBe(expected); }); + +test('Identify the longest string in an array', function (){ + const expected = 'encyclopedia'; + const result = functions.longestString(['hat', 'fish', 'abacus', 'encyclopedia' ]); + expect(result).toBe(expected); +}); + +test('Return an error value where there are two equally longest strings in an array', function (){ + const expected = -1; + const result = functions.longestString(['hat', 'fish', 'abacus', 'encyclopedia', 'encyclopedit' ]); + expect(result).toBe(expected); +}); + +// test('Turning a string into leetspeak requires input', function () { +// //const result = ; +// expect(functions.l337()).toThrow(); +// }); + +test('Turn a string into leetspeak', function () { + const expected = '0m6 7h15 15 50 1337 101'; + const result = functions.l337('omg this is so leet lol'); + expect(result).toBe(expected); +}); + +test('Return unique strings in an array', function() { + const expected = ['hat', 'fish', 'abacus', 'encyclopedia']; + const result = functions.uniqueStrings (['hat', 'fish', 'abacus', 'fish', 'encyclopedia', 'hat']) + expect(result).toEqual(expected); +}); + +test('Developer constructor returns an instance of Developer', function() { + const result = new functions.Developer('Jane Code', [ 'Ada', 'COBOL', 'FORTH' ]); + expect(result).toBeInstanceOf(functions.Developer); +}); + +test('Developer constructor returns a named developer with languages', function() { + const expected = { + name : 'Jane Code', + languages : [ 'Ada', 'COBOL', 'FORTH' ] + }; + const result = new functions.Developer('Jane Code', [ 'Ada', 'COBOL', 'FORTH' ]); + expect(result).toEqual(expected); +}); + +test('Developer can learn a language', function() { + let jane = new functions.Developer('Jane Code', [ 'Ada', 'COBOL', 'FORTH' ]); + jane.learnLanguage('PROLOG'); + const expected = { + name : 'Jane Code', + languages : [ 'Ada', 'COBOL', 'FORTH', 'PROLOG' ] + }; + expect(jane).toEqual(expected); +}); + +test('Garden constructors returns a garden with plants and quantities of each plant' , function(){ + const expected = { + dandelion : 5, + poppy : 6, + rose : 7, + tulip : 8 + } + const result = new functions.Garden({ + dandelion : 5, + poppy : 6, + rose : 7, + tulip : 8 + }); + expect(result).toEqual(expected); +}); + +test('Garden can receive more stock from an object', function() { + const expected = { + dandelion : 7, + poppy : 8, + posy : 4, + rose : 9, + tulip : 8 + }; + const result = new functions.Garden({ + dandelion : 5, + poppy : 6, + rose : 7, + tulip : 8 + }); + + result.plant({ + dandelion : 2, + poppy : 2, + posy : 4, + rose : 2 + }); + + expect(result).toEqual(expected); +}); + +test('Garden can be harvested to specification in an object', function() { + const expected = { + dandelion : 4, + poppy : 5, + tulip : 7 + }; + const result = new functions.Garden({ + dandelion : 5, + poppy : 6, + rose : 7, + tulip : 8 + }); + + result.harvest({ + dandelion : 1, + poppy : 1, + rose : 10, + tulip : 1, + daffodil : 1 + }); + + expect(result).toEqual(expected); +}); + +test('Return concatenated strings from array of Strings and Numbers', function(){ + const expected= 'I am going home!'; + const result= functions.stringsConcat(['I','am',1,0,123,'going', 2, 'home!']); + expect(result).toBe(expected) +}) + +test('Return an array of negative values from an input array of values', function() { + const expected = [ -5, -4, -3, -2, -1 ]; + const result = functions.negativeOnly([ 5, -5, 4, -4, 3, -3, 2, -2, 1, -1]); + expect(result).toEqual(expected); +}) + +test('Convert a string of space-separated words into a camelCase string', function(){ + const expected = 'aCamelCaseString'; + const result = functions.camelise('A Camel Case String'); + expect(result).toBe(expected); +}) + +test('The objects with fewest values should take precedence over objects with more values', function(){ + const expected = {a: 5, b: 2, c:32} + const result = functions.merging([{a: 5}, {a: 3, b: 21, c:32}, {b: 2}]) + expect(result).toEqual(expected); +}) + +test('Turn an array of objects into an object containing arrays of unique values', function(){ + const expected = {a:[5,3], b:[21], c:[32]}; + const result = functions.possibleValues([{a: 5}, {a: 3, b: 21, c:32}, {a: 3, c:32}]); + expect(result).toEqual(expected); +}) + +test('Check if the number is prime or not', function(){ + const prime= functions.isPrime(982451653); + expect(prime).toBe(true); + + const notPrime= functions.isPrime(982451658); + expect(notPrime).toBe(false); +}) + +test('Walker constructor with no direction returns a Walker facing N', function() { + const expected = { + direction : 'N', + coords : [0,0], + pathTaken : [[0,0]] + }; + const result = new functions.Walker(); + expect(result).toEqual(expected); +}); + +test('Walker constructor with direction E returns a Walker facing E', function() { + const expected = { + direction : 'E', + coords : [0,0], + pathTaken : [[0,0]] + }; + const result = new functions.Walker('E'); + expect(result).toEqual(expected); +}); + + +test('Walker constructor with bad direction returns a Walker facing N', function() { + const expected = { + direction : 'N', + coords : [0,0], + pathTaken : [[0,0]] + }; + const result = new functions.Walker('Dave'); + expect(result).toEqual(expected); +}); + +test('Walker walks to direction specified as many steps as given', function(){ + const expected = { + direction : 'N', + coords : [0,5], + pathTaken: [[0,0], [0,5]] + } + const walker = new functions.Walker('N'); + walker.walk('N',5); + expect(walker).toEqual(expected); +}) + +test('Output the journey history of a Walker as a list of coordinates', function() { + const walker = new functions.Walker('N'); + walker.walk('N', 5); + walker.walk('E', 2); + walker.walk('N', 3); + walker.walk('W', 7); + + const expected = [ [0,0], [0,5], [2,5], [2,8], [-5,8] ]; + expect(walker.pathTaken).toEqual(expected); +}) \ No newline at end of file