Skip to content

Commit c111a7e

Browse files
committed
feat(138 day): calculate sum of all divisors with optimized sqrt-based approach
1 parent c049f41 commit c111a7e

1 file changed

Lines changed: 75 additions & 0 deletions

File tree

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
"""
2+
Sum of Divisors
3+
Given a positive integer, return the sum of all its divisors.
4+
5+
A divisor is any integer that divides the number evenly (the remainder is 0).
6+
Only count each divisor once.
7+
For example, given 6, return 12 because the divisors of 6 are 1, 2, 3, and 6, and the sum of those is 12.
8+
9+
"""
10+
11+
import unittest
12+
13+
class SumOfDivisorsTest(unittest.TestCase):
14+
15+
def test1(self):
16+
self.assertEqual(sumDivisors(6), 12)
17+
18+
def test2(self):
19+
self.assertEqual(sumDivisors(13), 14)
20+
21+
def test3(self):
22+
self.assertEqual(sumDivisors(28), 56)
23+
24+
def test4(self):
25+
self.assertEqual(sumDivisors(84), 224)
26+
27+
def test5(self):
28+
self.assertEqual(sumDivisors(549), 806)
29+
30+
def test6(self):
31+
self.assertEqual(sumDivisors(9348), 23520)
32+
33+
34+
35+
def sumDivisors(n):
36+
total = 0
37+
for i in range(1, n + 1):
38+
if n % i == 0:
39+
total += i
40+
return total
41+
42+
import math
43+
def sumDivisors_optimized(n):
44+
total = 0
45+
for i in range(1, int(math.sqrt(n)) + 1):
46+
if n % i == 0:
47+
total += i
48+
if i != n // i: # avoid double-counting square roots
49+
total += n // i
50+
return total
51+
52+
53+
"""
54+
55+
When finding divisors of a number n, they always come in pairs:
56+
=> if i divides n, then n / i is also a divisor.
57+
=> Example: for n = 36:
58+
-> i = 2 -> divisor pair (2, 18)
59+
-> i = 3 -> divisor pair (3, 12)
60+
-> i = 6 -> divisor pair (6, 6) (special case)
61+
62+
=> So instead of looping all the way up to n, you only need to loop up to sqrt(n):
63+
-> Because beyond sqrt(n), divisors are just the "other half" of the pairs you already found.
64+
-> This reduces complexity from O(n) to O(√n), which is much faster for large numbers.
65+
66+
=> Brute force: loop from 1 to n.
67+
=> Optimized: loop to sqrt(n) and add divisor pairs.
68+
=> Both approaches give the correct sum, but the optimized one is much faster for large numbers.
69+
"""
70+
71+
72+
73+
if __name__ == "__main__":
74+
print(sumDivisors(15))
75+
unittest.main()

0 commit comments

Comments
 (0)