diff --git a/Maths/NarcissisticNumber.js b/Maths/NarcissisticNumber.js new file mode 100644 index 0000000000..8333519e45 --- /dev/null +++ b/Maths/NarcissisticNumber.js @@ -0,0 +1,27 @@ +/** + * @function isNarcissisticNumber + * @description A narcissistic number (also known as an Armstrong number) + * for a given number of digits n is a number that equals the sum of + * its digits each raised to the power n. This function checks all + * narcissistic numbers up to a given limit. + * @param {number} limit - A positive integer upper limit + * @returns {number[]} - Array of all narcissistic numbers up to limit + * @see https://en.wikipedia.org/wiki/Narcissistic_number + * @example getNarcissisticNumbers(500) => [1, 2, 3, 4, 5, 6, 7, 8, 9, 153, 370, 371, 407] + * @example getNarcissisticNumbers(10) => [1, 2, 3, 4, 5, 6, 7, 8, 9] + */ +const getNarcissisticNumbers = (limit) => { + if (!Number.isInteger(limit) || limit < 1) { + throw new TypeError('Input must be a positive integer') + } + const result = [] + for (let n = 1; n <= limit; n++) { + const digits = String(n).split('') + const power = digits.length + const sum = digits.reduce((acc, d) => acc + Math.pow(Number(d), power), 0) + if (sum === n) result.push(n) + } + return result +} + +export { getNarcissisticNumbers } diff --git a/Maths/test/NarcissisticNumber.test.js b/Maths/test/NarcissisticNumber.test.js new file mode 100644 index 0000000000..23a865b2b5 --- /dev/null +++ b/Maths/test/NarcissisticNumber.test.js @@ -0,0 +1,54 @@ +import { getNarcissisticNumbers } from '../NarcissisticNumber.js' + +describe('getNarcissisticNumbers', () => { + test('single digits 1-9 are all narcissistic', () => { + expect(getNarcissisticNumbers(9)).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9]) + }) + + test('getNarcissisticNumbers(10) returns [1..9]', () => { + expect(getNarcissisticNumbers(10)).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9]) + }) + + test('153 is narcissistic', () => { + const result = getNarcissisticNumbers(153) + expect(result).toContain(153) + }) + + test('370 is narcissistic', () => { + const result = getNarcissisticNumbers(370) + expect(result).toContain(370) + }) + + test('371 is narcissistic', () => { + const result = getNarcissisticNumbers(371) + expect(result).toContain(371) + }) + + test('407 is narcissistic', () => { + const result = getNarcissisticNumbers(407) + expect(result).toContain(407) + }) + + test('getNarcissisticNumbers(500) returns correct list', () => { + expect(getNarcissisticNumbers(500)).toEqual([ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 153, 370, 371, 407 + ]) + }) + + test('100 is NOT narcissistic', () => { + const result = getNarcissisticNumbers(100) + expect(result).not.toContain(100) + }) + + test('throws TypeError for zero', () => { + expect(() => getNarcissisticNumbers(0)).toThrow(TypeError) + }) + + test('throws TypeError for negative input', () => { + expect(() => getNarcissisticNumbers(-5)).toThrow(TypeError) + }) + + test('throws TypeError for float input', () => { + expect(() => getNarcissisticNumbers(9.5)).toThrow(TypeError) + }) +})