Skip to content

Commit ce61a9b

Browse files
authored
Merge pull request #59 from devNoiseConsulting/develop
Factorial
2 parents ba49c93 + faf5e2d commit ce61a9b

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

lib/factorial.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// https://stackoverflow.com/a/3959275
2+
3+
const { isPositiveInteger } = require('./isPositiveInteger');
4+
5+
const handleErrors = (params) => {
6+
if (params.length === 0) throw new Error('Must provide one or more paramters');
7+
if (params.some(param => !Number.isInteger(param))) {
8+
throw new Error('One of your parameters does not evaluate to a integer');
9+
}
10+
// Has to be a non negative integer
11+
if (params.some(param => !isPositiveInteger(param) && param !== 0)) {
12+
throw new Error('One of your parameters does not evaluate to a positive integer');
13+
}
14+
// JS can only safely represent integers less than Number.MAX_SAFE_INTEGER
15+
if (params.some(param => param > 18)) {
16+
throw new Error('Cannot reliably return numbers larger than 9,007,199,254,740,991');
17+
}
18+
};
19+
20+
const factorialCache = [1, 1];
21+
22+
const caclulateFactorial = (num) => {
23+
if (typeof factorialCache[num] !== 'undefined') {
24+
return factorialCache[num];
25+
}
26+
27+
const start = factorialCache.length;
28+
for (let i = start; i <= num; i += 1) {
29+
factorialCache[i] = factorialCache[i - 1] * i;
30+
}
31+
32+
return factorialCache[num];
33+
};
34+
35+
exports.factorial = (...params) => {
36+
handleErrors(params);
37+
38+
return params.map(caclulateFactorial);
39+
};

spec/factorialSpec.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
const { factorial } = require('../lib/factorial');
2+
3+
describe('factorial', () => {
4+
it('should return the factorial of all parameters, given that all parameters evaluate to numbers', () => {
5+
const result = factorial(0, 1, 2, 3, 4);
6+
expect(result).toEqual([1, 1, 2, 6, 24]);
7+
});
8+
9+
it('should throw an error when no parameters are provided', () => {
10+
expect(factorial).toThrow();
11+
});
12+
13+
it('should throw an error when at least one parameter does not evaluate to a number', () => {
14+
expect(() => factorial(1, 2, 'yo')).toThrow();
15+
});
16+
17+
it('should throw an error when at least one parameter evaluates to a negative number', () => {
18+
expect(() => factorial(1, 2, -1)).toThrow();
19+
});
20+
21+
it('should throw an error when at least one parameter evaluates to a number larger than 18', () => {
22+
expect(() => factorial(1, 2, Number.MAX_SAFE_INTEGER)).toThrow();
23+
});
24+
});

0 commit comments

Comments
 (0)