-
Notifications
You must be signed in to change notification settings - Fork 91
/
Copy pathkaratsuba.py
61 lines (47 loc) · 1.88 KB
/
karatsuba.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
# Purpose is to implement karatsuba multiplication, a way of computing
# x * y which is faster than the normal method taught at school which has a time complexity of O(n^2) which
# is very slow. This method produces a way which is much faster approx. O(n^(log2(3)))
# import random to check if implementation is correct
import random
def karatsuba(x, y):
# handle negative numbers multiplication
if x < 0:
return -1 * karatsuba(-x, y)
if y < 0:
return -1 * karatsuba(x, -y)
# Base case (two numbers from 1-9 multiplication)
if len(str(x)) == 1 or len(str(y)) == 1:
return x * y
n = max(len(str(x)), len(str(y)))
# split about middle (can be done in multiple ways, found on github, thought was rly clever)
a = x // 10 ** (n // 2)
b = x % 10 ** (n // 2)
c = y // 10 ** (n // 2)
d = y % 10 ** (n // 2)
# Compute the terms using recursion
ac = karatsuba(a, c)
bd = karatsuba(b, d)
ad_bc = karatsuba(a + b, c + d) - ac - bd
# calculate x * y
product = ac * (10 ** (2 * (n // 2))) + ad_bc * (10 ** (n // 2)) + bd
# return x * y
return product
# Following checks if implementation is correct
# if __name__ == '__main__':
# for _ in range(500):
# a = random.randint(-100000, 100000)
# b = random.randint(-100000, 100000)
# karatsuba_result = karatsuba(a, b)
# correct_result = a * b
#
# if karatsuba_result != correct_result:
# print('mismatch for %s and %s' % (a, b))
# print(f'Correct result was {correct_result}')
# print(f'Karatsuba method got it to {karatsuba_result}')
# break
# For Programming Assignment 1
if __name__ == "__main__":
x = 3141592653589793238462643383279502884197169399375105820974944592
y = 2718281828459045235360287471352662497757247093699959574966967627
print(karatsuba(x, y))
print(x * y)