11from __future__ import annotations # Enable modern type hints
2- from typing import overload
3-
42
53def 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
118119if __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 ("\n Calculating aliquot sum for 10^9..." )
0 commit comments