Skip to content

Commit b928e1f

Browse files
authored
Add binary exponentiation (#687)
* Add binary exponentiation * Export power functions * Fix bug in power_recur function * Add tests for power functions in power.py * Fix typo in test * Add power.py link to README.md
1 parent 81a19a7 commit b928e1f

File tree

4 files changed

+69
-0
lines changed

4 files changed

+69
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ If you want to uninstall algorithms, it is as simple as:
198198
- [is_isomorphic](algorithms/map/is_isomorphic.py)
199199
- [is_anagram](algorithms/map/is_anagram.py)
200200
- [maths](algorithms/maths)
201+
- [power](algorithms/maths/power.py)
201202
- [base_conversion](algorithms/maths/base_conversion.py)
202203
- [combination](algorithms/maths/combination.py)
203204
- [cosine_similarity](algorithms/maths/cosine_similarity.py)

algorithms/maths/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@
1818
from .find_order_simple import *
1919
from .find_primitive_root_simple import *
2020
from .diffie_hellman_key_exchange import *
21+
from .power import *

algorithms/maths/power.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
def power(a: int, n: int, r: int = None):
2+
"""
3+
Iterative version of binary exponentiation
4+
5+
Calculate a ^ n
6+
if r is specified, return the result modulo r
7+
8+
Time Complexity : O(log(n))
9+
Space Complexity : O(1)
10+
"""
11+
ans = 1
12+
while n:
13+
if n & 1:
14+
ans = ans * a
15+
a = a * a
16+
if r:
17+
ans %= r
18+
a %= r
19+
n >>= 1
20+
return ans
21+
22+
23+
def power_recur(a: int, n: int, r: int = None):
24+
"""
25+
Recursive version of binary exponentiation
26+
27+
Calculate a ^ n
28+
if r is specified, return the result modulo r
29+
30+
Time Complexity : O(log(n))
31+
Space Complexity : O(log(n))
32+
"""
33+
if n == 0:
34+
ans = 1
35+
elif n == 1:
36+
ans = a
37+
else:
38+
ans = power_recur(a, n // 2, r)
39+
ans = ans * ans
40+
if n % 2:
41+
ans = ans * a
42+
if r:
43+
ans %= r
44+
return ans
45+

tests/test_maths.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from algorithms.maths import (
2+
power,power_recur,
23
int_to_base, base_to_int,
34
decimal_to_binary_ip,
45
euler_totient,
@@ -25,6 +26,27 @@
2526
import unittest
2627

2728

29+
class TestPower(unittest.TestCase):
30+
"""
31+
Test for the file power.py
32+
33+
Arguments:
34+
unittest {[type]} -- [description]
35+
"""
36+
37+
def test_power(self):
38+
self.assertEqual(8, power(2, 3))
39+
self.assertEqual(1, power(5, 0))
40+
self.assertEqual(0, power(10, 3, 5))
41+
self.assertEqual(280380, power(2265, 1664,465465))
42+
43+
def test_power_recur(self):
44+
self.assertEqual(8, power_recur(2, 3))
45+
self.assertEqual(1, power_recur(5, 0))
46+
self.assertEqual(0, power_recur(10, 3, 5))
47+
self.assertEqual(280380, power_recur(2265, 1664,465465))
48+
49+
2850
class TestBaseConversion(unittest.TestCase):
2951
"""
3052
Test for the file base_conversion.py

0 commit comments

Comments
 (0)