From 6dfed7fcce4b6a268442da6c9b24423310139cf7 Mon Sep 17 00:00:00 2001 From: sarthakgupta1907-cell Date: Sat, 7 Nov 2026 02:20:30 +0530 Subject: [PATCH] feat: add happy number algorithm --- Maths/HappyNumber.js | 33 ++++++++++++++++++++++ Maths/test/HappyNumber.test.js | 51 ++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 Maths/HappyNumber.js create mode 100644 Maths/test/HappyNumber.test.js diff --git a/Maths/HappyNumber.js b/Maths/HappyNumber.js new file mode 100644 index 0000000000..f69a434163 --- /dev/null +++ b/Maths/HappyNumber.js @@ -0,0 +1,33 @@ +/** + * @function isHappyNumber + * @description A happy number is defined by the following process: + * Starting with any positive integer, replace the number by the sum + * of the squares of its digits, and repeat until the number equals 1 + * (where it will stay), or it loops endlessly in a cycle that does + * not include 1. + * @param {number} n - A positive integer + * @returns {boolean} - True if n is a happy number, false otherwise + * @see https://en.wikipedia.org/wiki/Happy_number + * @example isHappyNumber(19) => true + * @example isHappyNumber(7) => true + * @example isHappyNumber(4) => false + */ +const isHappyNumber = (n) => { + if (!Number.isInteger(n) || n < 1) { + throw new TypeError('Input must be a positive integer') + } + const sumOfSquares = (num) => + String(num) + .split('') + .reduce((sum, d) => sum + Number(d) ** 2, 0) + const seen = new Set() + let current = n + while (current !== 1) { + if (seen.has(current)) return false + seen.add(current) + current = sumOfSquares(current) + } + return true +} + +export { isHappyNumber } diff --git a/Maths/test/HappyNumber.test.js b/Maths/test/HappyNumber.test.js new file mode 100644 index 0000000000..30959acb53 --- /dev/null +++ b/Maths/test/HappyNumber.test.js @@ -0,0 +1,51 @@ +import { isHappyNumber } from '../HappyNumber.js' + +describe('isHappyNumber', () => { + test('1 is a happy number', () => { + expect(isHappyNumber(1)).toBe(true) + }) + + test('7 is a happy number', () => { + expect(isHappyNumber(7)).toBe(true) + }) + + test('19 is a happy number', () => { + expect(isHappyNumber(19)).toBe(true) + }) + + test('23 is a happy number', () => { + expect(isHappyNumber(23)).toBe(true) + }) + + test('100 is a happy number', () => { + expect(isHappyNumber(100)).toBe(true) + }) + + test('4 is NOT a happy number', () => { + expect(isHappyNumber(4)).toBe(false) + }) + + test('11 is NOT a happy number', () => { + expect(isHappyNumber(11)).toBe(false) + }) + + test('20 is NOT a happy number', () => { + expect(isHappyNumber(20)).toBe(false) + }) + + test('36 is NOT a happy number', () => { + expect(isHappyNumber(36)).toBe(false) + }) + + test('throws TypeError for zero', () => { + expect(() => isHappyNumber(0)).toThrow(TypeError) + }) + + test('throws TypeError for negative input', () => { + expect(() => isHappyNumber(-19)).toThrow(TypeError) + }) + + test('throws TypeError for float input', () => { + expect(() => isHappyNumber(19.5)).toThrow(TypeError) + }) +})