diff --git a/Maths/DigitalRoot.js b/Maths/DigitalRoot.js new file mode 100644 index 0000000000..abf64a234e --- /dev/null +++ b/Maths/DigitalRoot.js @@ -0,0 +1,21 @@ +/** + * @function digitalRoot + * @description The digital root is the single digit obtained by repeatedly + * summing the digits of a number until a single digit is reached. + * For example, 493: 4+9+3=16, 1+6=7 — digital root is 7. + * @param {number} n - A non-negative integer + * @returns {number} - The digital root of n + * @see https://en.wikipedia.org/wiki/Digital_root + * @example digitalRoot(493) => 7 + * @example digitalRoot(999) => 9 + * @example digitalRoot(0) => 0 + */ +const digitalRoot = (n) => { + if (!Number.isInteger(n) || n < 0) { + throw new TypeError('Input must be a non-negative integer') + } + if (n === 0) return 0 + return n % 9 === 0 ? 9 : n % 9 +} + +export { digitalRoot } diff --git a/Maths/test/DigitalRoot.test.js b/Maths/test/DigitalRoot.test.js new file mode 100644 index 0000000000..078cc88e2f --- /dev/null +++ b/Maths/test/DigitalRoot.test.js @@ -0,0 +1,51 @@ +import { digitalRoot } from '../DigitalRoot.js' + +describe('digitalRoot', () => { + test('digitalRoot(0) returns 0', () => { + expect(digitalRoot(0)).toBe(0) + }) + + test('digitalRoot(1) returns 1', () => { + expect(digitalRoot(1)).toBe(1) + }) + + test('digitalRoot(9) returns 9', () => { + expect(digitalRoot(9)).toBe(9) + }) + + test('digitalRoot(493) returns 7', () => { + expect(digitalRoot(493)).toBe(7) + }) + + test('digitalRoot(999) returns 9', () => { + expect(digitalRoot(999)).toBe(9) + }) + + test('digitalRoot(18) returns 9', () => { + expect(digitalRoot(18)).toBe(9) + }) + + test('digitalRoot(99) returns 9', () => { + expect(digitalRoot(99)).toBe(9) + }) + + test('digitalRoot(100) returns 1', () => { + expect(digitalRoot(100)).toBe(1) + }) + + test('digitalRoot(12345) returns 6', () => { + expect(digitalRoot(12345)).toBe(6) + }) + + test('throws TypeError for negative input', () => { + expect(() => digitalRoot(-493)).toThrow(TypeError) + }) + + test('throws TypeError for float input', () => { + expect(() => digitalRoot(4.93)).toThrow(TypeError) + }) + + test('throws TypeError for string input', () => { + expect(() => digitalRoot('493')).toThrow(TypeError) + }) +})