diff --git a/Maths/MultiplicativePersistence.js b/Maths/MultiplicativePersistence.js new file mode 100644 index 0000000000..0235c993e6 --- /dev/null +++ b/Maths/MultiplicativePersistence.js @@ -0,0 +1,28 @@ +/** + * @function multiplicativePersistence + * @description Multiplicative persistence is the number of times you must + * multiply the digits of a number until you reach a single digit. + * For example, 39: 3×9=27, 2×7=14, 1×4=4 — persistence is 3. + * @param {number} n - A non-negative integer + * @returns {number} - The multiplicative persistence of n + * @see https://en.wikipedia.org/wiki/Persistence_of_a_number + * @example multiplicativePersistence(39) => 3 + * @example multiplicativePersistence(999) => 4 + * @example multiplicativePersistence(4) => 0 + */ +const multiplicativePersistence = (n) => { + if (!Number.isInteger(n) || n < 0) { + throw new TypeError('Input must be a non-negative integer') + } + let count = 0 + let current = n + while (current >= 10) { + current = String(current) + .split('') + .reduce((product, d) => product * Number(d), 1) + count++ + } + return count +} + +export { multiplicativePersistence } diff --git a/Maths/test/MultiplicativePersistence.test.js b/Maths/test/MultiplicativePersistence.test.js new file mode 100644 index 0000000000..0a9ba23b56 --- /dev/null +++ b/Maths/test/MultiplicativePersistence.test.js @@ -0,0 +1,51 @@ +import { multiplicativePersistence } from '../MultiplicativePersistence.js' + +describe('multiplicativePersistence', () => { + test('single digit returns 0', () => { + expect(multiplicativePersistence(4)).toBe(0) + }) + + test('multiplicativePersistence(10) returns 1', () => { + expect(multiplicativePersistence(10)).toBe(1) + }) + + test('multiplicativePersistence(25) returns 2', () => { + expect(multiplicativePersistence(25)).toBe(2) + }) + + test('multiplicativePersistence(39) returns 3', () => { + expect(multiplicativePersistence(39)).toBe(3) + }) + + test('multiplicativePersistence(77) returns 4', () => { + expect(multiplicativePersistence(77)).toBe(4) + }) + + test('multiplicativePersistence(999) returns 4', () => { + expect(multiplicativePersistence(999)).toBe(4) + }) + + test('multiplicativePersistence(0) returns 0', () => { + expect(multiplicativePersistence(0)).toBe(0) + }) + + test('multiplicativePersistence(1) returns 0', () => { + expect(multiplicativePersistence(1)).toBe(0) + }) + + test('multiplicativePersistence(100) returns 1', () => { + expect(multiplicativePersistence(100)).toBe(1) + }) + + test('throws TypeError for negative input', () => { + expect(() => multiplicativePersistence(-39)).toThrow(TypeError) + }) + + test('throws TypeError for float input', () => { + expect(() => multiplicativePersistence(3.9)).toThrow(TypeError) + }) + + test('throws TypeError for string input', () => { + expect(() => multiplicativePersistence('39')).toThrow(TypeError) + }) +})