diff --git a/CONTRACT.md b/CONTRACT.md index 831bfbc..5b01d97 100644 --- a/CONTRACT.md +++ b/CONTRACT.md @@ -32,12 +32,12 @@ Complete **ONLY** the [Classic](https://github.com/GuildCrafts/core-algorithms/b - [x] Tests for `fizzBuzz()` exist. - [x] `isPalindrome()` algorithm is implemented according to the description in [algorithms.md][algorithms-list]. - [x] Tests for `isPalindrome()` exist with at least 2 unit tests using valid inputs. -- [ ] `factorial()` algorithm is implemented according to the description in [algorithms.md][algorithms-list]. -- [ ] Tests for `factorial()` exist with at least 2 unit tests using valid inputs. -- [ ] `fibonacci()` algorithm is implemented according to the description in [algorithms.md][algorithms-list]. -- [ ] Tests for `fibonacci()` exist with at least 2 unit tests using valid inputs, and at least 1 unit test using invalid inputs. -- [ ] `collatzConjecture()` algorithm is implemented according to the description in [algorithms.md][algorithms-list]. -- [ ] Tests for `collatzConjecture()` exist with at least 2 unit tests using valid inputs, and at least 1 unit test using invalid inputs. +- [x] `factorial()` algorithm is implemented according to the description in [algorithms.md][algorithms-list]. +- [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][algorithms-list]. +- [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][algorithms-list]. +- [x] Tests for `collatzConjecture()` exist with at least 2 unit tests using valid inputs, and at least 1 unit test using invalid inputs. - [ ] `setUnion()` algorithm is implemented according to the description in [algorithms.md][algorithms-list]. - [ ] Tests for `setUnion()` exist with at least 2 unit tests using valid inputs, and at least 1 unit test using invalid inputs. - [ ] `setIntersection()` algorithm is implemented according to the description in [algorithms.md][algorithms-list]. diff --git a/src/collatzConjecture.js b/src/collatzConjecture.js new file mode 100644 index 0000000..3f5a5e1 --- /dev/null +++ b/src/collatzConjecture.js @@ -0,0 +1,32 @@ +// collatzConjecture +// +// Return the Collatz sequence for a given number. +// +// The Collatz sequence for any positive integer n is defined as follows: +// +// If n is even, divide it by 2 to get n / 2. If n is odd, multiply it by 3 and add 1 to obtain 3n + 1. Repeat the process until you reach 1. +// collatzConjecture(1) +// // => [1] +// +// collatzConjecture(7) +// // => [7, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1] + + +export default function collatzConjecture(num) { + if (!Number.isInteger(num) || num < 0) { + throw new Error('Invalid input format. Expected a positive integer') + } + let collatzArr = [num] + let result = num + + while (result > 1) { + if (result % 2 === 0) { + result = result / 2 + collatzArr.push(result) + } else { + result = (result * 3) + 1 + collatzArr.push(result) + } + } + return collatzArr +} diff --git a/src/factorial.js b/src/factorial.js new file mode 100644 index 0000000..cb8372f --- /dev/null +++ b/src/factorial.js @@ -0,0 +1,16 @@ +// factorial +// +// Return the factorial of a number. +// +// factorial(5) +// // => 120 + +export default function factorial(num) { + var factorialElements = [num] + for (var i = num; i > 1; i--) { + factorialElements.push(i - 1) + } + return factorialElements.reduce(function(a,b){ + return a*b + }, 1) +} diff --git a/src/fibonacci.js b/src/fibonacci.js new file mode 100644 index 0000000..88a9a4a --- /dev/null +++ b/src/fibonacci.js @@ -0,0 +1,24 @@ +// fibonacci +// +// Return an array of Fibonacci numbers to the nth position. +// +// fibonacci(10) +// // => [0, 1, 1, 2, 3, 5, 8, 13, 21, 34] + +export default function fibonacci(num) { + if (typeof num !== 'number') { + throw new Error('Invalid input format. Expected a number') + } + var first = 0 + var second = 1 + var result + var fibonacciArr = [0] + + for (var i = 1; i < num; i++) { + result = first + second + first = second + second = result + fibonacciArr.push(first) + } + return fibonacciArr +} diff --git a/test/collatzConjecture_test.js b/test/collatzConjecture_test.js new file mode 100644 index 0000000..c895ca0 --- /dev/null +++ b/test/collatzConjecture_test.js @@ -0,0 +1,18 @@ +import { expect } from 'chai' +import collatzConjecture from '../src/collatzConjecture' + +describe('collatzConjecture()', function(){ + + it('should be a function', function(){ + expect(collatzConjecture).to.be.a('function') + }) + it('returns a Collatz sequence for any positive integer', function(){ + expect(collatzConjecture(7)).to.eql([7, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1]) + expect(collatzConjecture(3)).to.eql([3, 10, 5, 16, 8, 4, 2, 1]) + }) + + it('throws an error for any invalid inputs', function() { + expect(function() {collatzConjecture(-1)}).to.throw('Invalid input format. Expected a positive integer') + expect(function() {collatzConjecture('seven')}).to.throw('Invalid input format. Expected a positive integer') + }) +}) diff --git a/test/factorial_test.js b/test/factorial_test.js new file mode 100644 index 0000000..12daa9e --- /dev/null +++ b/test/factorial_test.js @@ -0,0 +1,14 @@ +import { expect } from 'chai' +import factorial from '../src/factorial' + +describe('factorial()', function(){ + + it('should be a function', function(){ + expect(factorial).to.be.a('function') + }) + + it('returns the factorial of any fiven number', function() { + expect(factorial(5)).to.eql(120) + expect(factorial(4)).to.eql(24) + }) +}) diff --git a/test/fibonacci_test.js b/test/fibonacci_test.js new file mode 100644 index 0000000..06154f6 --- /dev/null +++ b/test/fibonacci_test.js @@ -0,0 +1,18 @@ +import { expect } from 'chai' +import fibonacci from '../src/fibonacci' + +describe ('fibonacci', function(){ + + it('should be a function', function() { + expect(fibonacci).to.be.a('function') + }) + + it('returns an array of Fibonacci numbers to the nth position.', function() { + expect(fibonacci(10)).to.eql([0, 1, 1, 2, 3, 5, 8, 13, 21, 34]) + expect(fibonacci(5)).to.eql([0, 1, 1, 2, 3]) + }) + + it('throws an error when given invalid inputs', function() { + expect(function() {fibonacci('five') }).to.throw('Invalid input format. Expected a number') + }) +}) diff --git a/test/makeChange_test.js b/test/makeChange_test.js index 2ca1a8a..9956816 100644 --- a/test/makeChange_test.js +++ b/test/makeChange_test.js @@ -53,13 +53,13 @@ describe('makeChange()', function(){ it('throws an error when given invalid inputs', function() { expect(function(){ makeChange(100, 170) }).to.throw( - 'Invalid input format. Expected an object literal' + 'Invalid input format. Expected an object' ) }) it('throws an error when given no arguments', function() { expect(function(){ makeChange() }).to.throw( - 'Invalid input format. Expected an object literal' + 'Invalid input format. Expected an object' ) }) })