DEV Community

Shahrouz Nikseresht
Shahrouz Nikseresht

Posted on

Day 40: Python Armstrong Numbers Finder, Detect Narcissistic Numbers in a Range with Digit Power Sum

Welcome to Day 40 of the #80DaysOfChallenges journey! This intermediate challenge explores finding Armstrong numbers (also called narcissistic numbers) in a given range, where a number equals the sum of its own digits each raised to the power of the number of digits. It combines digit extraction via strings, exponentiation, loop-based checking, and a helper function for clean logic, making it a solid exercise in numeric manipulation and conditionals. If you're advancing from basic loops to algorithmic checks or enjoy math-inspired problems, this "Python Armstrong numbers" script demonstrates a function that's efficient for reasonable ranges and easy to extend for larger bounds or optimizations.


💡 Key Takeaways from Day 40: Armstrong Number Checker

This task features a core is_armstrong function that verifies a single number, used in a range loop to collect matches with input validation. It's a classic pattern: convert to string for digits, compute power sum, compare. We'll detail: helper with string digit access, range loop with collection, and input handling with guards.

1. Checker Function: String-Based Digit Power Sum

The is_armstrong function determines if n qualifies:

def is_armstrong(n: int) -> bool:
    """
    Return True if n is an Armstrong number.
    """
    s = str(n)
    power = len(s)
    total = 0

    # Sum each digit raised to 'power'
    for d in s:
        total += int(d) ** power

    return total == n
Enter fullscreen mode Exit fullscreen mode

Converting to string gives easy digit access and len for power (e.g., 153 has 3 digits). Loop converts each char digit back to int, raises to power, sums. Compares to original n. For 153: 1^3 + 5^3 + 3^3 = 1 + 125 + 27 = 153, True. Handles singles (1-9 are Armstrong) and zeros correctly.

2. Range Search: Input, Validation, Collection

Main script prompts and scans:

start = int(input("Start: "))
end = int(input("End: "))

# Validate range
if start < 0 or end < 0:
    print("Range must contain non-negative integers only.")
    raise SystemExit

if start > end:
    print("Invalid range: start must be <= end.")
    raise SystemExit

# Collect Armstrong numbers
armstrong_nums = []

for num in range(start, end + 1):
    if is_armstrong(num):
        armstrong_nums.append(num)
Enter fullscreen mode Exit fullscreen mode

Validates non-negative and order, exits cleanly on issues. Loops inclusive end+1, appends matches. Efficient for typical ranges (up to ~10^6), as string ops scale with digits (~log n).

3. Output: List or None Found

Final print:

# Output result
if armstrong_nums:
    print("Armstrong numbers in this range:")
    print(*armstrong_nums)
else:
    print("No Armstrong numbers found in this range.")
Enter fullscreen mode Exit fullscreen mode

Uses * for space-separated list, clean for few results. Handles empty gracefully.


🎯 Summary and Reflections

This Armstrong finder blends math and code cleanly, using string digits for simplicity. It reinforced:

  • Digit extraction: String over mod/division, readable and fast enough.
  • Power reuse: Len once for exponent.
  • Validation early: Guards prevent bad runs.

Known Armstrongs are rare (only 88 below 10^18), so outputs sparse. For fun, precompute list.

Advanced Alternatives: Math way: while n: digit = n%10; total += digit**power; n//=10. Or generator for infinite. Your math check? Share!


🚀 Next Steps and Resources

Day 40 mixed math with loops, ready for number theory. In #80DaysOfChallenges? Found big ones? Post!

Top comments (0)