Happy Number
The drill: Repeatedly replace a number with the sum of the squares of its digits and watch where it goes: some numbers eventually settle on 1, others fall into a repeating loop that never reaches it. Decide which fate this one has.
A positive integer arrives, and the drill repeatedly replaces it with the sum of the squares of its own digits, watching where that chain of replacements eventually leads.
Some starting numbers eventually land on exactly 1 and stay there — those are the ones the drill calls happy. Others fall into a repeating cycle of values that never includes 1 at all, looping forever instead of settling.
The answer is a single true or false: true the moment the chain reaches 1, false once it becomes clear the chain has looped back into a cycle it can never escape.
- input is a positive integer, generally well under a billion
- the digit-square-sum chain from any such number always shrinks fast
- every starting number either reaches 1 or falls into a repeating cycle — no third outcome
- the answer is a single boolean, not the chain itself
HINT 1 THE NUDGE
Every number under about a billion collapses within a few steps to something small — so the sequence either reaches 1, or it must eventually repeat a value it's already visited. There's no third option.
HINT 2 THE STRUCTURE
Remembering every value seen so far settles the question the moment a repeat shows up — but that memory grows with the walk. Two runners at different speeds can detect the same repeat without remembering anything at all.
HINT 3 ONE STEP FROM THE ANSWER
Run a slow pointer one digit-square-sum step at a time and a fast pointer two steps at a time, exactly like cycle detection on a linked list. If they ever meet on a value other than 1, the number loops forever; if either hits 1, it's happy.
Start the digit-square-sum chain at 7. Slow moves one step at a time; fast takes its head start of two.
class Solution:
def isHappy(self, n: int) -> bool:
def next_value(x: int) -> int:
return sum(int(d) ** 2 for d in str(x))
slow, fast = n, next_value(n)
while fast != 1 and slow != fast:
slow = next_value(slow)
fast = next_value(next_value(fast))
return fast == 1class Solution:
def isHappy(self, n: int) -> bool:
def next_value(x: int) -> int:
return sum(int(d) ** 2 for d in str(x))
seen = set()
while n != 1 and n not in seen:
seen.add(n)
n = next_value(n)
return n == 1class Solution {
public boolean isHappy(int n) {
int slow = n, fast = nextValue(n);
while (fast != 1 && slow != fast) {
slow = nextValue(slow);
fast = nextValue(nextValue(fast));
}
return fast == 1;
}
private int nextValue(int x) {
int sum = 0;
while (x > 0) {
int digit = x % 10;
sum += digit * digit;
x /= 10;
}
return sum;
}
}class Solution {
public boolean isHappy(int n) {
Set<Integer> seen = new HashSet<>();
while (n != 1 && !seen.contains(n)) {
seen.add(n);
n = nextValue(n);
}
return n == 1;
}
private int nextValue(int x) {
int sum = 0;
while (x > 0) {
int digit = x % 10;
sum += digit * digit;
x /= 10;
}
return sum;
}
}✓ CHIP-TIMED — ALL 4 SOLUTIONS RAN GREEN AGAINST SELF-AUTHORED CASES IN CI · JDK 21 · CPYTHON 3.12 · NOTHING PUBLISHES RED