Skip to content

Commit b4b1a81

Browse files
authored
Update aliquot_sum.py
1 parent 3c73639 commit b4b1a81

1 file changed

Lines changed: 36 additions & 37 deletions

File tree

maths/aliquot_sum.py

Lines changed: 36 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,26 @@
11
from __future__ import annotations # Enable modern type hints
2-
from typing import overload
3-
42

53
def aliquot_sum(
64
input_num: int, return_factors: bool = False
75
) -> int | tuple[int, list[int]]:
86
"""
97
Calculates the aliquot sum of a positive integer. The aliquot sum is defined as
108
the sum of all proper divisors of a number (all divisors except the number itself).
11-
9+
1210
This implementation uses an optimized O(sqrt(n)) algorithm for efficiency.
13-
11+
1412
Args:
1513
input_num: Positive integer to calculate aliquot sum for
1614
return_factors: If True, returns tuple (aliquot_sum, sorted_factor_list)
17-
15+
1816
Returns:
1917
Aliquot sum if return_factors=False
2018
Tuple (aliquot_sum, sorted_factor_list) if return_factors=True
21-
19+
2220
Raises:
2321
TypeError: If input is not an integer
2422
ValueError: If input is not positive
25-
23+
2624
Examples:
2725
>>> aliquot_sum(15)
2826
9
@@ -34,42 +32,42 @@ def aliquot_sum(
3432
# Validate input type - must be integer
3533
if not isinstance(input_num, int):
3634
raise TypeError("Input must be an integer")
37-
35+
3836
# Validate input value - must be positive
3937
if input_num <= 0:
4038
raise ValueError("Input must be positive integer")
41-
39+
4240
# Special case: 1 has no proper divisors
4341
if input_num == 1:
4442
# Return empty factor list if requested
4543
return (0, []) if return_factors else 0
46-
44+
4745
# Initialize factors list with 1 (always a divisor)
48-
factors = [1]
46+
factors = [1]
4947
total = 1 # Start sum with 1
50-
48+
5149
# Calculate square root as optimization boundary
5250
sqrt_num = int(input_num**0.5)
53-
51+
5452
# Iterate potential divisors from 2 to square root
5553
for divisor in range(2, sqrt_num + 1):
5654
# Check if divisor is a factor
5755
if input_num % divisor == 0:
5856
# Add divisor to factors list
5957
factors.append(divisor)
6058
total += divisor
61-
59+
6260
# Calculate complement (pair factor)
6361
complement = input_num // divisor
64-
62+
6563
# Avoid duplicate for perfect squares
66-
if complement != divisor:
64+
if complement != divisor:
6765
factors.append(complement)
6866
total += complement
69-
67+
7068
# Sort factors for consistent output
7169
factors.sort()
72-
70+
7371
# Return based on return_factors flag
7472
return (total, factors) if return_factors else total
7573

@@ -80,16 +78,16 @@ def classify_number(n: int) -> str:
8078
- Perfect: aliquot sum = number
8179
- Abundant: aliquot sum > number
8280
- Deficient: aliquot sum < number
83-
81+
8482
Args:
8583
n: Positive integer to classify
86-
84+
8785
Returns:
8886
Classification string ("Perfect", "Abundant", or "Deficient")
89-
87+
9088
Raises:
9189
ValueError: If input is not positive
92-
90+
9391
Examples:
9492
>>> classify_number(6)
9593
'Perfect'
@@ -101,38 +99,39 @@ def classify_number(n: int) -> str:
10199
# Validate input
102100
if n <= 0:
103101
raise ValueError("Input must be positive integer")
104-
102+
105103
# Special case: 1 is always deficient
106104
if n == 1:
107105
return "Deficient"
108-
109-
# Calculate aliquot sum (using only the integer version)
110-
s = aliquot_sum(n) # Default returns only integer
111-
106+
107+
# Explicitly request integer-only aliquot sum
108+
s = aliquot_sum(n, return_factors=False)
109+
112110
# Determine classification
113111
if s == n:
114112
return "Perfect"
115-
return "Abundant" if s > n else "Deficient"
113+
elif s > n:
114+
return "Abundant"
115+
else:
116+
return "Deficient"
116117

117118

118119
if __name__ == "__main__":
119120
import doctest
120-
121+
121122
# Run embedded doctests for verification
122123
doctest.testmod()
123-
124+
124125
# Additional demonstration examples
125126
print("Aliquot sum of 28:", aliquot_sum(28)) # Perfect number
126-
127+
127128
# Get factors for 28 with type-safe access
128129
factor_result = aliquot_sum(28, return_factors=True)
129-
# Since we know return_factors=True returns a tuple, we can safely unpack
130-
if isinstance(factor_result, tuple):
131-
_, factors = factor_result
132-
print("Factors of 28:", factors)
133-
130+
# Since we requested factors, we know it's a tuple
131+
print("Factors of 28:", factor_result[1])
132+
134133
print("Classification of 28:", classify_number(28))
135-
134+
136135
# Large number performance test with targeted exception handling
137136
try:
138137
print("\nCalculating aliquot sum for 10^9...")

0 commit comments

Comments
 (0)