- Path
- 82 → 68 → 100 → 1
Check Happy Number in JavaScript
What you’ll learn
- The happy iteration: replace
nby the sum of squared decimal digits until1or a repeat. - Visited-sum detection with a
Setuntil you hit1or repeat (see FAQ for Floyd’sO(1)-memory variant). - A range scan for happy numbers in
[1, 50], plus a live preview and unhappy-cycle notes.
Overview
Happy numbers are a small playground for iteration and cycle detection. The digit-square map has finite image for bounded n, so every orbit eventually cycles; our programs remember visited sums in a Set until 1 or the first repeat.
Two programs
19 classification and 1–50 listing from the reference.
Live preview
Positive safe integers; same visited-sum logic as the tutorial scripts.
Rigor
Positive definition, known unhappy cycle, and why storing visited sums correctly spots repeats.
Prerequisites
Digit extraction with % 10 and Math.floor(n / 10), loops, and functions returning booleans.
console.log,Number.isSafeInteger,forloops.Set/ object maps for visited values; Floyd (FAQ) trades memory for two pointers.
What is a happy number?
Let f(n) be the sum of the squares of the decimal digits of n. Starting from a positive integer n, iterate n ← f(n). If you reach 1, the start was happy; otherwise you enter a cycle that never contains 1.
For 19: 82 → 68 → 100 → 1, so 19 is happy (as in the reference walkthrough).
Digit map
For n = ∑ di 10i with digits di ∈ {0,…,9}, define f(n) = ∑ di2. Happy numbers are exactly those n whose forward orbit under f reaches 1.
f(19)12 + 92 = 82, then 82 + 22 = 68, 62 + 82 = 100, 12 + 02 + 02 = 1.
Intuition
- Enters
- 4 → 16 → … cycle
Takeaway: you never need unbounded memory: either you hit 1 or you eventually repeat.
Live preview
Positive integers in the JavaScript safe range. Uses the same Set-based detector as the examples below.
Algorithm
Goal: decide whether iterating f (sum of squared digits) reaches 1.
Implement f(n)
Peel decimal digits with n % 10, square, accumulate, assign n = Math.floor(n / 10).
Detect repeat or reach 1
Keep applying f. If 1 appears, happy. If you revisit any earlier sum, you found a non-1 cycle (not happy). A Set stores visited sums; Floyd (FAQ) does this with O(1) extra memory instead.
📜 Pseudocode
function sum_square_digits(n):
s = 0
while n > 0:
d = n mod 10
s += d * d
n = floor(n / 10)
return s
function is_happy(n):
seen = empty set
cur = n
while cur != 1:
if cur in seen:
return false
seen.add(cur)
cur = sum_square_digits(cur)
return trueSingle value: 19
Same structure as the reference: sumOfSquares, isHappy with a visited Set. Rejects n < 1 before classifying.
function sumOfSquares(n) {
let sum = 0;
while (n > 0) {
const digit = n % 10;
sum += digit * digit;
n = Math.floor(n / 10);
}
return sum;
}
function isHappy(n) {
const seen = new Set();
let cur = n;
while (cur !== 1) {
if (seen.has(cur)) {
return false;
}
seen.add(cur);
cur = sumOfSquares(cur);
}
return true;
}
const number = 19;
if (number < 1) {
console.log("Use a positive integer.");
} else if (isHappy(number)) {
console.log(number + " is a Happy Number.");
} else {
console.log(number + " is not a Happy Number.");
}Explanation
When n = 1, the while guard fails immediately and returns true. Otherwise each new sum is checked against seen before continuing.
Happy numbers in [1, 50]
Same output as the reference listing. Prints the header line, then space-separated happy values, then a newline.
function sumOfSquares(num) {
let sum = 0;
while (num > 0) {
const digit = num % 10;
sum += digit * digit;
num = Math.floor(num / 10);
}
return sum;
}
function isHappy(num) {
const seen = new Set();
let cur = num;
while (cur !== 1) {
if (seen.has(cur)) {
return false;
}
seen.add(cur);
cur = sumOfSquares(cur);
}
return true;
}
console.log("Happy numbers in the range 1 to 50:");
const parts = [];
for (let i = 1; i <= 50; i++) {
if (isHappy(i)) {
parts.push(String(i));
}
}
console.log(parts.join(" "));Explanation
Each i is tested independently; each happy check allocates a fresh Set sized by the orbit length (tiny here).
Alternatives
Visited set. Store values in a Set until repeat or 1—simple to code, O(k) memory for orbit length k.
Hard-coded cycle. Because every unhappy orbit hits the 4 → … cycle, you can return false as soon as any of those eight values appears—fast constants, less general pedagogy.
Interview: explain Floyd correctness (two speeds on a functional graph eventually meet inside the unique cycle).
❓ FAQ
🔄 Input / output examples
Change number in Example 1 or the loop bounds in Example 2.
| n | Happy? |
|---|---|
1 | Yes |
7 | Yes |
2 | No |
19 | Yes |
Edge cases and pitfalls
Assume sumOfSquares is pure; accidental mutation of the visited structure would hide repeats.
Immediate happy
The do…while still runs one round; both pointers land on 1 and stop.
Not positive
Digit loop yields 0; the orbit sticks at 0, not 1. Treat n < 1 separately in APIs.
Very large n
digit * digit fits in Number for decimal digits; iterated sums shrink quickly. Stay within safe integers or switch to BigInt if you extend the puzzle.
Other radices
Happy-base-b definitions replace decimal digits with base-b digits; results differ from base 10.
⏱️ Time and space complexity
| Method | Time (per check) | Extra space |
|---|---|---|
| Set visited sums (this page) | O(μ + λ) digit-squaring steps | O(k) for orbit length k |
| Floyd tortoise-and-hare | same asymptotic steps | O(1) |
Scan [1, N] | O(N) checks | O(1) beyond each check |
Here μ is the tail length before the cycle and λ the cycle length under f.
Summary
- Happy: iterated digit-square sums eventually hit
1. - Detection: remember digit-square sums in a
Setuntil1or repeat (see FAQ for Floyd). - Watch-outs: define behavior for
n < 1; know the standard unhappy cycle.
If a positive integer is not happy, iterating digit-square sums always falls into the same unhappy cycle 4 → 16 → 37 → 58 → 89 → 145 → 42 → 20 → 4 (so Floyd’s detection need not store the whole path).
8 people found this page helpful
