diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..7f419db --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,28 @@ +module.exports = { + "env": { + "es6": true, + "node": true + }, + "extends": "eslint:recommended", + "parserOptions": { + "sourceType": "module" + }, + "rules": { + "indent": [ + "error", + "tab" + ], + "linebreak-style": [ + "error", + "unix" + ], + "quotes": [ + "error", + "single" + ], + "semi": [ + "error", + "never" + ] + } +}; \ No newline at end of file diff --git a/README.md b/README.md index 783e9c5..e33f79a 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,71 @@ -# Core Algorithms +# Installation and Setup -Tests and implementations for algorithms commonly used in job interviews. See the full list in the [algorithms.md](algorithms.md) file. +Installing your dependencies from the package.json file using ```npm install``` -Base repository for the [Core Algorithms](http://jsdev.learnersguild.org/goals/123) goal. +## Usage and Examples -## Installation and Setup +### Factorial -_Fill this out_ +Returns factorial of number passed in -## Usage and Examples +``` +let multiplyNumbers = [] + +for (let i = input; i > 1; i--) { + multiplyNumbers.push(i) +} +return multiplyNumbers.reduce(function(a, b) {return a * b}) +} +``` + +### Factorial Testing + +``` +import { expect } from 'chai' +import factorial from '../src/factorial' + +describe.only('factorial()', function(){ + + it('should be a function', function(){ + expect(factorial).to.be.a('function') + }) + + it('returns factorial of number passed in', function(){ + expect(factorial(5)).to.deep.equal(120) + expect(factorial(10)).to.deep.equal(3628800) + }) +}) +``` + + +# Core Algorithms [Classic, Numeric, Set] -_...and this_ +- [x] Artifact produced is a fork of the [core-algorithms][core-algorithms] repo. +- [x] Can run all tests with npm test. +- [x] ```makeChange()``` algorithm is implemented according to the description in algorithms.md. +- [x] Tests for ```makeChange()``` exist with at least 2 unit tests using valid inputs, and at least 1 unit test using invalid inputs. +- [x] ```fizzBuzz()``` algorithm is implemented according to the description in algorithms.md. +- [x] Tests for ```fizzBuzz()``` exist. +- [x] ```isPalindrome()``` algorithm is implemented according to the description in algorithms.md. +- [x] Tests for ```isPalindrome()``` exist with at least 2 unit tests using valid inputs. +- [x] ```factorial()``` algorithm is implemented according to the description in algorithms.md. +- [x] Tests for ```factorial()``` exist with at least 2 unit tests using valid inputs. +- [x] ```fibonacci()``` algorithm is implemented according to the description in algorithms.md. +- [x] Tests for ```fibonacci()``` exist with at least 2 unit tests using valid inputs, and at least 1 unit test using invalid inputs. +- [x] ```collatzConjecture()``` algorithm is implemented according to the description in algorithms.md. +- [x] Tests for ```collatzConjecture()``` exist with at least 2 unit tests using valid inputs, and at least 1 unit test using invalid inputs. +- [x] ```setUnion()``` algorithm is implemented according to the description in algorithms.md. +- [x] Tests for ```setUnion()``` exist with at least 2 unit tests using valid inputs, and at least 1 unit test using invalid inputs. +- [x] ```setIntersection()``` algorithm is implemented according to the description in algorithms.md. +- [x] Tests for ```setIntersection()``` exist with at least 2 unit tests using valid inputs, and at least 1 unit test using invalid inputs. +- [x] ```setComplement()``` algorithm is implemented according to the description in algorithms.md. +- [x] Tests for ```setComplement()``` exist with at least 2 unit tests using valid inputs, and at least 1 unit test using invalid inputs. +- [x] ```setSymmetricDifference()``` algorithm is implemented according to the description in algorithms.md. +- [x] Tests for ```setSymmetricDifference()``` exist with at least 2 unit tests using valid inputs, and at least 1 unit test using invalid inputs. +- [x] Repository includes a README file with basic installation and setup instructions. +- [x] All dependencies are properly declared in package.json. +- [x] All major features are added via pull requests with a clear description and concise commit messages. +- [x] Code uses a linter and there are no linting errors. +- [x] Variables, functions, files, etc. have appropriate and meaningful names. +- [x] Functions are small and serve a single purpose. +- [x] The artifact produced is properly licensed, preferably with the [MIT license][mit-license]. diff --git a/package.json b/package.json index 71f93c5..4b82682 100644 --- a/package.json +++ b/package.json @@ -3,11 +3,14 @@ "description": "Tests and implementations for algorithms commonly used in job interviews.", "private": false, "version": "0.0.0", - "devDependencies": { + "dependencies": { "babel-cli": "^6.18.0", "babel-preset-env": "^1.1.4", "babel-register": "^6.18.0", "chai": "~1.8.0", + "eslint": "^3.19.0", + "eslint-config-airbnb-base": "^11.1.3", + "eslint-plugin-import": "^2.2.0", "mocha": "2.0.1" }, "scripts": { diff --git a/src/collatzConjecture.js b/src/collatzConjecture.js new file mode 100644 index 0000000..5cabc36 --- /dev/null +++ b/src/collatzConjecture.js @@ -0,0 +1,23 @@ +export default function collatzConjecture(input) { + + let finalArray = [], + currentNumber = input + + if (!Number.isInteger(input)) { + return undefined + } else if (input === 1) { + return [1]; + } else { + while (currentNumber !== 1) { + if (currentNumber % 2 === 0) { + finalArray.push(currentNumber) + currentNumber = currentNumber / 2 + } else { + finalArray.push(currentNumber) + currentNumber = (currentNumber * 3) + 1 + } + } + finalArray.push(currentNumber) + return finalArray + } +} diff --git a/src/factorial.js b/src/factorial.js new file mode 100644 index 0000000..8376a1e --- /dev/null +++ b/src/factorial.js @@ -0,0 +1,9 @@ +export default function factorial(input) { + + let multiplyNumbers = [] + + for (let i = input; i > 1; i--) { + multiplyNumbers.push(i) + } + return multiplyNumbers.reduce(function(a, b) {return a * b}) +} diff --git a/src/fibonacci.js b/src/fibonacci.js new file mode 100644 index 0000000..688ea63 --- /dev/null +++ b/src/fibonacci.js @@ -0,0 +1,18 @@ +export default function fibonacci(input) { + + const fibArray = [0, 1] + + if (!Number.isInteger(input) || input < 1) { + return undefined + } else if (input === 1) { + return [0] + } else if (input === 2) { + return fibArray + } else { + for (let i = 2; i < input; i++) { + let current = fibArray[i - 1] + fibArray[i - 2] + fibArray.push(current) + } + } + return fibArray +} diff --git a/src/fizzBuzz.js b/src/fizzBuzz.js new file mode 100644 index 0000000..62f2231 --- /dev/null +++ b/src/fizzBuzz.js @@ -0,0 +1,17 @@ + export default function fizzBuzz() { + + let fizzBuzzArray = [] + + for (let i = 1; i <= 100; i++) { + if (i % 15 === 0) { + fizzBuzzArray.push('FizzBuzz') + } else if (i % 3 === 0) { + fizzBuzzArray.push('Fizz') + } else if (i % 5 === 0) { + fizzBuzzArray.push('Buzz') + } else { + fizzBuzzArray.push(i) + } + } + return fizzBuzzArray + } diff --git a/src/isPalindrome.js b/src/isPalindrome.js new file mode 100644 index 0000000..e3ff8d5 --- /dev/null +++ b/src/isPalindrome.js @@ -0,0 +1,7 @@ +export default function isPalindrome(input) { + + const condensedString = input.replace(/[\W_]+/g, '').toLowerCase() + const reversedString = condensedString.split('').reverse().join('') + return condensedString === reversedString + +} diff --git a/src/makeChange.js b/src/makeChange.js index 59d89b1..e31b0ac 100644 --- a/src/makeChange.js +++ b/src/makeChange.js @@ -1,3 +1,30 @@ -export default function makeChange({price, amountGiven}) { - // your code here + export default function makeChange({price, amountGiven}) { + + let changeNeeded = amountGiven - price, + coinChange = {quarters: 0, dimes: 0, nickels: 0, pennies: 0} + + if (amountGiven < price) { + return 'Gimme more money!' + } + + while (changeNeeded >= 25) { + coinChange.quarters++ + changeNeeded -= 25 + } + + while (changeNeeded >= 10) { + coinChange.dimes++ + changeNeeded -= 10 + } + + while (changeNeeded >= 5) { + coinChange.nickels++ + changeNeeded -= 5 + } + + while (changeNeeded >= 1) { + coinChange.pennies++ + changeNeeded -= 1 + } + return coinChange } diff --git a/src/setComplement.js b/src/setComplement.js new file mode 100644 index 0000000..6ab1bc8 --- /dev/null +++ b/src/setComplement.js @@ -0,0 +1,8 @@ +export default function setComplement(firstSet, secondSet) { + + const intersection = new Set([...secondSet].filter(x => !firstSet.includes(x))) + + if (!firstSet || !secondSet) { + return undefined + } return Array.from(intersection) +} diff --git a/src/setIntersection.js b/src/setIntersection.js new file mode 100644 index 0000000..2b3f3b4 --- /dev/null +++ b/src/setIntersection.js @@ -0,0 +1,8 @@ +export default function setIntersecion(firstSet, secondSet) { + + const intersection = new Set([...firstSet].filter(x => secondSet.includes(x))) + + if (!firstSet || !secondSet) { + return undefined + } return Array.from(intersection) +} diff --git a/src/setSymmetricDifference.js b/src/setSymmetricDifference.js new file mode 100644 index 0000000..db58f15 --- /dev/null +++ b/src/setSymmetricDifference.js @@ -0,0 +1,14 @@ +export default function setSymmetricDifference(firstSet, secondSet) { + + const intersection = new Set([...firstSet].filter(x => !secondSet.includes(x))) + const intersection2 = new Set([...secondSet].filter(x => !firstSet.includes(x))) + + const intersectionArray = Array.from(intersection) + const intersectionArray2 = Array.from(intersection2) + + const setArray = intersectionArray.concat(intersectionArray2) + + if (!firstSet || !secondSet) { + return undefined + } return setArray +} diff --git a/src/setUnion.js b/src/setUnion.js new file mode 100644 index 0000000..c7fb421 --- /dev/null +++ b/src/setUnion.js @@ -0,0 +1,9 @@ +export default function setUnion(firstSet, secondSet) { + + if (!firstSet || !secondSet) { + return undefined + } else { + let finalSet = new Set([...firstSet, ...secondSet]) + return Array.from(finalSet) + } +} diff --git a/test/collatzConjecture_test.js b/test/collatzConjecture_test.js new file mode 100644 index 0000000..41a81ff --- /dev/null +++ b/test/collatzConjecture_test.js @@ -0,0 +1,38 @@ +import { expect } from 'chai'; +import collatzConjecture from '../src/collatzConjecture'; + +describe.only('collatzConjecture()', () => { + it('should be a function', () => { + expect(collatzConjecture).to.be.a('function'); + }); + + it('should give you an array of [1] when handed 1', () => { + expect(collatzConjecture(1)).to.deep.equal([1]); + }); + + it('should give you a lengthy array when handed 7', () => { + expect(collatzConjecture(7)).to.deep.equal( + [7, + 22, + 11, + 34, + 17, + 52, + 26, + 13, + 40, + 20, + 10, + 5, + 16, + 8, + 4, + 2, + 1]); + }); + + it('should not evaluate non-numerical values', () => { + expect(collatzConjecture('string')).to.equal(undefined); + expect(collatzConjecture(['string'])).to.equal(undefined); + }); +}); diff --git a/test/factorial_test.js b/test/factorial_test.js new file mode 100644 index 0000000..6818a3b --- /dev/null +++ b/test/factorial_test.js @@ -0,0 +1,14 @@ +import { expect } from 'chai' +import factorial from '../src/factorial' + +describe.only('factorial()', function(){ + + it('should be a function', function(){ + expect(factorial).to.be.a('function') + }) + + it('returns an array of numbers 1-100, fizz for multiples of 3, buzz for multiples of 5, fizzbuzz for multiples of 3 and five', function(){ + expect(factorial(5)).to.deep.equal(120) + expect(factorial(10)).to.deep.equal(3628800) + }) +}) diff --git a/test/fibonacci_test.js b/test/fibonacci_test.js new file mode 100644 index 0000000..b2c1387 --- /dev/null +++ b/test/fibonacci_test.js @@ -0,0 +1,26 @@ +import { expect } from 'chai'; +import fibonacci from '../src/fibonacci'; + +describe.only('fibonacci()', () => { + it('should be a function', () => { + expect(fibonacci).to.be.a('function'); + }); + + it('should output an array', () => { + expect(fibonacci(1)).to.be.a('array'); + }); + + it('should give a proper array', () => { + expect(fibonacci(10)).to.deep.equal([0, 1, 1, 2, 3, 5, 8, 13, 21, 34]); + }); + + it('should not try to run the function with the values of empty things', () => { + expect(fibonacci({})).to.equal(undefined); + expect(fibonacci('')).to.equal(undefined); + expect(fibonacci([])).to.equal(undefined); + }); + + it('should not let you plug in negitive integers', () => { + expect(fibonacci(-5)).to.equal(undefined); + }); +}); diff --git a/test/fizzBuzz_test.js b/test/fizzBuzz_test.js new file mode 100644 index 0000000..16d125d --- /dev/null +++ b/test/fizzBuzz_test.js @@ -0,0 +1,114 @@ +import { expect } from 'chai' +import fizzBuzz from '../src/fizzBuzz' + +describe('fizzBuzz()', function(){ + + it('should be a function', function(){ + expect(fizzBuzz).to.be.a('function') + }) + + it('returns an array of numbers 1-100, fizz for multiples of 3, buzz for multiples of 5, fizzbuzz for multiples of 3 and five', function(){ + expect(fizzBuzz()).to.deep.equal([ + 1, + 2, + 'Fizz', + 4, + 'Buzz', + 'Fizz', + 7, + 8, + 'Fizz', + 'Buzz', + 11, + 'Fizz', + 13, + 14, + 'FizzBuzz', + 16, + 17, + 'Fizz', + 19, + 'Buzz', + 'Fizz', + 22, + 23, + 'Fizz', + 'Buzz', + 26, + 'Fizz', + 28, + 29, + 'FizzBuzz', + 31, + 32, + 'Fizz', + 34, + 'Buzz', + 'Fizz', + 37, + 38, + 'Fizz', + 'Buzz', + 41, + 'Fizz', + 43, + 44, + 'FizzBuzz', + 46, + 47, + 'Fizz', + 49, + 'Buzz', + 'Fizz', + 52, + 53, + 'Fizz', + 'Buzz', + 56, + 'Fizz', + 58, + 59, + 'FizzBuzz', + 61, + 62, + 'Fizz', + 64, + 'Buzz', + 'Fizz', + 67, + 68, + 'Fizz', + 'Buzz', + 71, + 'Fizz', + 73, + 74, + 'FizzBuzz', + 76, + 77, + 'Fizz', + 79, + 'Buzz', + 'Fizz', + 82, + 83, + 'Fizz', + 'Buzz', + 86, + 'Fizz', + 88, + 89, + 'FizzBuzz', + 91, + 92, + 'Fizz', + 94, + 'Buzz', + 'Fizz', + 97, + 98, + 'Fizz', + 'Buzz', + ]) + }) +}) diff --git a/test/isPalindrome_test.js b/test/isPalindrome_test.js new file mode 100644 index 0000000..1513163 --- /dev/null +++ b/test/isPalindrome_test.js @@ -0,0 +1,14 @@ +import { expect } from 'chai'; +import isPalindrome from '../src/isPalindrome'; + +describe('isPalindrome()', () => { + it('should be a function', () => { + expect(isPalindrome).to.be.a('function'); + }); + + it('Determine if a string is a palindrome. Return true or false.Ignore punctuation, spacing, and case sensitivity.)', () => { + expect(isPalindrome('radar')).to.equal(true); + expect(isPalindrome('bananas')).to.equal(false); + expect(isPalindrome('A man, a plan, a canal: Panama')).to.equal(true); + }); +}); diff --git a/test/makeChange_test.js b/test/makeChange_test.js index d17098e..bc569cb 100644 --- a/test/makeChange_test.js +++ b/test/makeChange_test.js @@ -1,7 +1,7 @@ import { expect } from 'chai' import makeChange from '../src/makeChange' -describe('makeChange()', function(){ +describe.only('makeChange()', function(){ it('should be a function', function(){ expect(makeChange).to.be.a('function') @@ -49,5 +49,7 @@ describe('makeChange()', function(){ nickels: 0, pennies: 0, }) + + expect(makeChange({price: 100, amountGiven: 99})).to.deep.equal('Gimme more money!') }) }) diff --git a/test/setComplement_test.js b/test/setComplement_test.js new file mode 100644 index 0000000..38f222a --- /dev/null +++ b/test/setComplement_test.js @@ -0,0 +1,24 @@ +import { expect } from 'chai'; +import setComplement from '../src/setComplement'; + +describe.only('setComplement()', () => { + it('should be a function', () => { + expect(setComplement).to.be.a('function'); + }); + + it('Return the symmetric difference of two sets.', () => { + const firstSet = [1, 2, 3, 4]; + const secondSet = [2, 4, 6, 8]; + expect(setComplement(firstSet, secondSet)).to.deep.equal([6, 8]); + }); + + it('Return the symmetric difference of two sets.', () => { + const firstSet = [3, 6, 9, 12]; + const secondSet = [6, 7, 8, 9]; + expect(setComplement(firstSet, secondSet)).to.deep.equal([7, 8]); + }); + + it('Will not try to evaluate empty things', () => { + expect(setComplement('', '')).to.equal(undefined); + }); +}); diff --git a/test/setIntersection_test.js b/test/setIntersection_test.js new file mode 100644 index 0000000..4c3e5d6 --- /dev/null +++ b/test/setIntersection_test.js @@ -0,0 +1,24 @@ +import { expect } from 'chai'; +import setIntersection from '../src/setIntersection'; + +describe('setIntersection()', () => { + it('should be a function', () => { + expect(setIntersection).to.be.a('function'); + }); + + it('Return the intersection of two sets.', () => { + const firstSet = [1, 2, 3, 4]; + const secondSet = [2, 4, 6, 8]; + expect(setIntersection(firstSet, secondSet)).to.deep.equal([2, 4]); + }); + + it('Return the intersection of two sets.', () => { + const firstSet = [3, 6, 9, 12]; + const secondSet = [6, 7, 8, 9]; + expect(setIntersection(firstSet, secondSet)).to.deep.equal([6, 9]); + }); + + it('Will not try to evaluate empty things', () => { + expect(setIntersection('', '')).to.equal(undefined); + }); +}); diff --git a/test/setSymmetricDifference_test.js b/test/setSymmetricDifference_test.js new file mode 100644 index 0000000..780c9fc --- /dev/null +++ b/test/setSymmetricDifference_test.js @@ -0,0 +1,24 @@ +import { expect } from 'chai'; +import setSymmetricDifference from '../src/setSymmetricDifference'; + +describe('setSymmetricDifference()', () => { + it('should be a function', () => { + expect(setSymmetricDifference).to.be.a('function'); + }); + + it('Return the symmetric difference of two sets.', () => { + const firstSet = [1, 2, 3, 4]; + const secondSet = [2, 4, 6, 8]; + expect(setSymmetricDifference(firstSet, secondSet)).to.deep.equal([1, 3, 6, 8]); + }); + + it('Return the symmetric difference of two sets.', () => { + const firstSet = [3, 6, 9, 12]; + const secondSet = [6, 7, 8, 9]; + expect(setSymmetricDifference(firstSet, secondSet)).to.deep.equal([3, 12, 7, 8]); + }); + + it('Will not try to evaluate empty things', () => { + expect(setSymmetricDifference('', '')).to.equal(undefined); + }); +}); diff --git a/test/setUnion_test.js b/test/setUnion_test.js new file mode 100644 index 0000000..1f8dcad --- /dev/null +++ b/test/setUnion_test.js @@ -0,0 +1,24 @@ +import { expect } from 'chai'; +import setUnion from '../src/setUnion'; + +describe('setUnion()', () => { + it('should be a function', () => { + expect(setUnion).to.be.a('function'); + }); + + it('Return the union of two sets.', () => { + const firstSet = [1, 2, 3, 4]; + const secondSet = [2, 4, 6, 8]; + expect(setUnion(firstSet, secondSet)).to.deep.equal([1, 2, 3, 4, 6, 8]); + }); + + it('Return the union of two sets.', () => { + const firstSet = [3, 6, 9, 12]; + const secondSet = [6, 7, 8, 9]; + expect(setUnion(firstSet, secondSet)).to.deep.equal([3, 6, 9, 12, 7, 8]); + }); + + it('Will not try to evaluate empty things', () => { + expect(setUnion('', '')).to.equal(undefined); + }); +});