Skip to content

Commit ab2949e

Browse files
committed
Added an explanation and examples to the README
1 parent 6975842 commit ab2949e

File tree

1 file changed

+122
-1
lines changed

1 file changed

+122
-1
lines changed
Lines changed: 122 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,129 @@
11
# Karatsuba Multiplication
22

3-
TODO: Explanation/Examples
3+
Goal: To quickly multiply two numbers together
44

5+
## Long Multiplication
56

7+
In grade school we all learned how to multiply two numbers together via Long Multiplication. So let's try that first!
68

9+
Example 1: Multiply 1234 by 5678 using Long Multiplication
10+
11+
5678
12+
*1234
13+
------
14+
22712
15+
17034-
16+
11356--
17+
5678---
18+
--------
19+
7006652
20+
21+
So what's the problem with long multiplication? Speed. Long Multiplication runs in **O(n^2)**.
22+
23+
You can see where the **O(n^2)** comes from in the implementation for Long Multiplication:
24+
25+
```swift
26+
// Long Multiplication
27+
func multiply(_ num1: Int, by num2: Int, base: Int = 10) -> Int {
28+
let num1Array = String(num1).characters.reversed().map{ Int(String($0))! }
29+
let num2Array = String(num2).characters.reversed().map{ Int(String($0))! }
30+
31+
var product = Array(repeating: 0, count: num1Array.count + num2Array.count)
32+
33+
for i in num1Array.indices {
34+
var carry = 0
35+
for j in num2Array.indices {
36+
product[i + j] += carry + num1Array[i] * num2Array[j]
37+
carry = product[i + j] / base
38+
product[i + j] %= base
39+
}
40+
product[i + num2Array.count] += carry
41+
}
42+
43+
return Int(product.reversed().map{ String($0) }.reduce("", +))!
44+
}
45+
```
46+
47+
The double for loop is the culprit! So Long Multiplication might not be the best algorithm after all. Can we do better?
48+
49+
## Karatsuba Multiplication
50+
51+
The Karatsuba Algorithm was discovered by Anatoly Karatsuba and published in 1962. Karatsuba discovered that you could compute the product of two large numbers using three smaller products and some addition and subtraction.
52+
53+
For two numbers x, y, where m <= n:
54+
55+
x = a*10^m + b
56+
y = c*10^m + d
57+
58+
Now, we can say:
59+
60+
x*y = a*c*10^(2m) + (a*d + b*c)*10^(m) + b*d
61+
62+
We can compute this function recursively, and that's what makes Karatsuba Multiplication fast.
63+
64+
```swift
65+
let ac = karatsuba(a, by: c)
66+
let bd = karatsuba(b, by: d)
67+
let adPlusbc = karatsuba(a+b, by: c+d) - ac - bd
68+
```
69+
70+
The last recursion is interesting. Normally, you'd think we would have to run four recursions to find the product `x*y` (`a*c`, `a*d`, `b*c`, `b*d`). However, Karatsuba realized that you only need three recursions, and some addition and subtraction. Here's the math:
71+
72+
(a+b)*(c+d) - a*c - b*c = (a*c + a*d + b*c + b*d) - a*c - b*c
73+
= (a*d + b*c)
74+
75+
Pretty cool, huh?
76+
77+
Here's the full implementation
78+
79+
```swift
80+
// Karatsuba Multiplication
81+
func karatsuba(_ num1: Int, by num2: Int) -> Int {
82+
let num1Array = String(num1).characters
83+
let num2Array = String(num2).characters
84+
85+
guard num1Array.count > 1 && num2Array.count > 1 else {
86+
return num1*num2
87+
}
88+
89+
let n = max(num1Array.count, num2Array.count)
90+
let nBy2 = n / 2
91+
92+
let a = num1 / 10^^nBy2
93+
let b = num1 % 10^^nBy2
94+
let c = num2 / 10^^nBy2
95+
let d = num2 % 10^^nBy2
96+
97+
let ac = karatsuba(a, by: c)
98+
let bd = karatsuba(b, by: d)
99+
let adPlusbc = karatsuba(a+b, by: c+d) - ac - bd
100+
101+
let product = ac * 10^^(2 * nBy2) + adPlusbc * 10^^nBy2 + bd
102+
103+
return product
104+
}
105+
```
106+
107+
The run time for this algorithm is about **O(n^1.56)** which is better than the **O(n^2)** for Long Multiplication.
108+
109+
Example 2: Multiply 1234 by 5678 using Karatsuba Multiplication
110+
111+
m = 2
112+
x = 1234 = a*10^2 + b = 12*10^2 + 34
113+
y = 5678 = c*10^2 + d = 56*10^2 + 78
114+
115+
a*c = 672
116+
b*d = 2652
117+
(a*d + b*c) = 2840
118+
119+
x*y = 672*10^4 + 2840*10^2 + 2652
120+
= 6720000 + 284000 + 2652
121+
= 7006652
122+
123+
## Resources
124+
125+
[Wikipedia] (https://en.wikipedia.org/wiki/Karatsuba_algorithm)
126+
127+
[WolframMathWorld] (http://mathworld.wolfram.com/KaratsubaMultiplication.html)
7128

8129
*Written for Swift Algorithm Club by Richard Ash*

0 commit comments

Comments
 (0)