From e298f3afd1d8e201c52976c1fddaffe65b8ce392 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20E=C3=9Flinger?= Date: Sat, 8 Oct 2022 16:13:15 +0200 Subject: [PATCH] feat(maths): add `Factorial` (#38) --- Maths/Factorial.ts | 16 ++++++++++++++++ Maths/test/Factorial.test.ts | 23 +++++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 Maths/Factorial.ts create mode 100644 Maths/test/Factorial.test.ts diff --git a/Maths/Factorial.ts b/Maths/Factorial.ts new file mode 100644 index 00000000..1783383b --- /dev/null +++ b/Maths/Factorial.ts @@ -0,0 +1,16 @@ +/** + * @function Factorial + * @description Calculate the factorial of a natural number. + * @param {number} num - A natural number. + * @return {number} - The factorial. + * @see https://en.wikipedia.org/wiki/Factorial + * @example Factorial(0) = 1 + * @example Factorial(3) = 6 + */ +export const Factorial = (num: number): number => { + if (num < 0 || !Number.isInteger(num)) { + throw new Error("only natural numbers are supported"); + } + + return num === 0 ? 1 : num * Factorial(num - 1); +}; diff --git a/Maths/test/Factorial.test.ts b/Maths/test/Factorial.test.ts new file mode 100644 index 00000000..5ce5ccba --- /dev/null +++ b/Maths/test/Factorial.test.ts @@ -0,0 +1,23 @@ +import { Factorial } from "../Factorial"; + +describe("Factorial", () => { + test.each([-0.1, -1, -2, -42, 0.01, 0.42, 0.5, 1.337])( + "should throw an error for non natural number %d", + (num) => { + expect(() => Factorial(num)).toThrowError( + "only natural numbers are supported", + ); + }, + ); + + test.each([[1, 1], [3, 6], [5, 120], [10, 3628800]])( + "of %i should be %i", + (num, expected) => { + expect(Factorial(num)).toBe(expected); + }, + ); + + test("of 1 should be 0 by definition", () => { + expect(Factorial(0)).toBe(1); + }); +});