|
| 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