DEV Community

Shahrouz Nikseresht
Shahrouz Nikseresht

Posted on

Day 41: Python Happy Number Checker, Detect Numbers Leading to 1 Through Digit Square Sums with Cycle Detection

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
Enter fullscreen mode Exit fullscreen mode

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)")
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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!

Top comments (0)