forked from TheAlgorithms/Python
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathbinary_exp_mod.py
96 lines (77 loc) · 2.89 KB
/
binary_exp_mod.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
def bin_exp_mod(a, n, b):
"""
>>> bin_exp_mod(3, 4, 5)
1
>>> bin_exp_mod(7, 13, 10)
7
"""
# mod b
assert not (b == 0), "This cannot accept modulo that is == 0"
if n == 0:
return 1
if n % 2 == 1:
return (bin_exp_mod(a, n - 1, b) * a) % b
r = bin_exp_mod(a, n / 2, b)
return (r * r) % b
def binary_exponentiation_mod_multiplication(a, b, c):
"""
* Binary Exponentiation with Multiplication
* This is a method to find a*b in a time complexity of O(log b)
* This is one of the most commonly used methods of finding result of multiplication.
* Also useful in cases where solution to (a*b)%c is required,
* where a,b,c can be numbers over the computers calculation limits.
* Done using iteration, can also be done using recursion
* Let's say you need to calculate a ^ b
* RULE 1 : a * b = (a+a) * (b/2) -- example : 4 * 4 = (4+4) * (4/2) = 8 * 2
* RULE 2 : IF b is ODD, then -- a * b = a + (a * (b - 1)) :: where (b - 1) is even.
* Once b is even, repeat the process to get a * b
* Repeat the process till b = 1 OR b = 0, because a*1 = a AND a*0 = 0
*
* As far as the modulo is concerned,
* the fact : (a+b) % c = ((a%c) + (b%c)) % c
* Now apply RULE 1 OR 2, whichever is required.
* @author chinmoy159
* @version 1.0 dated 10/08/2017
"""
res = 0
while b > 0:
if b & 1:
res = ((res % c) + (a % c)) % c
a += a
b >>= 1
return res
def binary_exponentiation_mod_powers(a, b, c):
"""
* Binary Exponentiation for Powers
* This is a method to find a^b in a time complexity of O(log b)
* This is one of the most commonly used methods of finding powers.
* Also useful in cases where solution to (a^b)%c is required,
* where a,b,c can be numbers over the computers calculation limits.
* Done using iteration, can also be done using recursion
* Let's say you need to calculate a ^ b
* RULE 1 : a ^ b = (a*a) ^ (b/2) -- example : 4 ^ 4 = (4*4) ^ (4/2) = 16 ^ 2
* RULE 2 : IF b is ODD, then -- a ^ b = a * (a ^ (b - 1)) :: where (b - 1) is even.
* Once b is even, repeat the process to get a ^ b
* Repeat the process till b = 1 OR b = 0, because a^1 = a AND a^0 = 1
*
* As far as the modulo is concerned,
* the fact : (a*b) % c = ((a%c) * (b%c)) % c
* Now apply RULE 1 OR 2 whichever is required.
* @author chinmoy159
* @version 1.0 dated 10/08/2017
"""
res = 1
while b > 0:
if b & 1:
res = ((res % c) * (a % c)) % c
a *= a
b >>= 1
return res
if __name__ == "__main__":
try:
BASE = int(input("Enter Base : ").strip())
POWER = int(input("Enter Power : ").strip())
MODULO = int(input("Enter Modulo : ").strip())
except ValueError:
print("Invalid literal for integer")
print(bin_exp_mod(BASE, POWER, MODULO))