Welcome to Day 41 of the #80DaysOfChallenges journey! This intermediate challenge explores checking if a number is a Happy Number within an interactive script, where a happy number is one that, when repeatedly replaced by the sum of the squares of its digits, eventually reaches 1, while unhappy ones loop in a cycle without hitting 1. It combines digit extraction in a math-based loop, set-based cycle detection to avoid infinite runs, and sequence tracking for step-by-step output, making it a strong exercise in loop control, modular functions, and algorithmic termination. If you're advancing from basic numeric loops to problems involving cycles and state tracking, or enjoy puzzles with mathematical flair, this "Python happy number checker" script demonstrates functions that are efficient, visual with printed sequences, and easy to extend for range searches or variant rules like sad number cycles.
💡 Key Takeaways from Day 41: Happy Number Checker
This task features a helper function for digit squaring sums and a main checker that uses a set for cycle detection while building and printing the transformation sequence. It's a classic algorithmic pattern: iterate transformations, track seen states, terminate on 1 or cycle. We'll detail: helper with math digit extraction, main loop with set and list for sequence, and input handling with positivity check.
1. Squaring Helper: Math-Based Digit Extraction
The sum_of_squares function computes the sum of squared digits for a number:
def sum_of_squares(n: int) -> int:
"""
Return the sum of the squares of the digits of n.
"""
total = 0
while n > 0:
digit = n % 10
total += digit ** 2
n //= 10
return total
This uses modulo (%) to get the last digit and integer division (//) to remove it, looping until n is 0. For 19: 9*2=81, n=1; 1*2=1, total=82. It's efficient, O(d) where d is digits (log n), and avoids string conversion for purity. Handles 0 as 0, positives only per input.
2. Main Checker: Cycle Detection and Sequence Print
The is_happy function runs the process, detects cycles, builds steps, and prints:
def is_happy(number: int) -> None:
"""
Determine if 'number' is a happy number.
Prints the full transformation sequence.
"""
seen = set() # To detect cycles
steps = [] # To display the sequence
while number != 1 and number not in seen:
seen.add(number)
steps.append(number)
number = sum_of_squares(number)
steps.append(number) # Add final number (1 or repeated number)
# Print the sequence
print(" → ".join(map(str, steps)))
if number == 1:
print(f"Number {steps[0]} is a Happy Number! 🎉")
else:
print(f"Number {steps[0]} is NOT a Happy Number 😢 (stuck in a cycle)")
Set seen tracks visited numbers for O(1) checks, stopping on repeat. List steps collects for arrow-joined print (e.g., "7 → 49 → 97 → 130 → 10 → 1"). Loop condition ensures termination. For unhappy, ends on cycle start like 4. Prints result with emoji for fun.
3. Input Handling: Positivity Guard and Call
Script prompts and calls:
num = int(input("Enter a positive number: "))
if num < 1:
print("Please enter a positive integer.")
else:
is_happy(num)
Converts input to int (assumes valid, add try for robustness), skips if <1. Calls function for check and print.
🎯 Summary and Reflections
This happy checker merges math intrigue with code logic, using sets for safe iteration. It reinforced:
- Digit ops: Mod/div loop for extraction, scalable.
- Cycle safety: Set prevents infinite, key for algorithms.
- Visual output: Steps print educates on process.
Happy numbers are infinite but sparse, all unhappy end in 4-cycle. For fun, count happies in range.
Advanced Alternatives: String sum: sum(int(d)**2 for d in str(n)). Floyd's two-pointer for cycle without set. Your cycle detect? Share!
🚀 Next Steps and Resources
Day 41 added algorithmic depth, prepping for graph problems. In #80DaysOfChallenges? Checked ranges? Post!
- Source Code for Challenge #41: scripts/happy_number.py
- Main Repository: 80-days-of-challenges
- Daily Updates: Twitter/X (@Shahrouzlogs)
Top comments (0)