The Balanced Sum
An easy Python interview practice problem on DataDriven. Write the Python and run it against test cases, with instant feedback.
- Domain
- Python
- Difficulty
- easy
- Seniority
- L3
- Asked in
- Citadel
Problem
A reviewer auditing a number-theory quiz bank flags an integer as perfect when it equals the sum of all its positive divisors smaller than itself. Given a positive integer n, report whether it qualifies.
Some numbers have a rare quality that mathematicians revere.
Example 1
Input:
n = 28
Output:
true
Example 2
Input:
n = 12
Output:
false
Worked solution and explanation
This is a divisor-sum check dressed up as a quiz-bank audit, and the only line that separates candidates is the first one. Everyone writes the loop. The tell is the seed: start divisor_sum at 1 because 'every number is divisible by 1' and you have quietly assumed n > 1. Feed it n = 1 and the seed alone equals n, so the function calls 1 perfect. The guard that rejects n <= 1 before seeding is the difference between a pass and a confident wrong answer on the smallest input there is.
Getting there
Step 1: Settle the tiny input first
1 has no divisor below itself, so its total is 0 and the answer is False. Return early for n <= 1. After that guard, 1 is a genuine smaller divisor of every remaining n, and seeding the sum with it is safe.
Step 2: Walk candidates only up to the square root
Divisors come in pairs: if candidate divides n, so does n // candidate, and one of the two is never above the square root. Testing while candidate * candidate <= n finds every pair in about sqrt(n) checks instead of n.
Step 3: Count a square's root once
When partner == candidate the pair collapses to a single divisor. Adding it twice inflates the total on inputs like 36, which is harmless there but wrong in principle, and interviewers ask about it.
Step 4: Compare the total to n
Starting the walk at 2 keeps n out of the sum by construction: its partner is 1, which the seed already covers. Equality with n is the whole answer.
def is_perfect_number(n):
if n <= 1:
return False
# 1 divides every n above 1; starting at 2 keeps n itself out of the sum
divisor_sum = 1
candidate = 2
while candidate * candidate <= n:
if n % candidate == 0:
partner = n // candidate
divisor_sum += candidate
if partner != candidate:
divisor_sum += partner
candidate += 1
return divisor_sum == n- Seed, then loop
divisor_sum = 1with no guard is correct for everynabove 1, butn = 1returns True because the seed already matches it.- Guard, then seed
if n <= 1: return Falseruns first, so the seed of 1 is always a real divisor belownby the time it is added.
Common follow-up questions
- What are the first few perfect numbers? (Tests knowledge: 6, 28, 496, 8128. They are rare, and every known one is even.)
- What is the relationship to Mersenne primes? (Tests number theory: every even perfect number has the form `2**(p - 1) * (2**p - 1)` where `2**p - 1` is prime.)
- How would you classify a number as abundant or deficient instead? (Tests reuse of the same divisor sum: greater than `n` is abundant, less is deficient.)