Follow the pseudocode more closely
This commit is contained in:
parent
101ad7e177
commit
dc45e09b24
3 changed files with 75 additions and 15 deletions
28
python/calculators/karatsuba algorithm.md
Normal file
28
python/calculators/karatsuba algorithm.md
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
### Useful Links
|
||||||
|
|
||||||
|
- [Wikipedia](https://en.wikipedia.org/wiki/Karatsuba_algorithm)
|
||||||
|
- [An amazing video on the topic](https://youtu.be/cCKOl5li6YM)
|
||||||
|
|
||||||
|
### The Pseudocode
|
||||||
|
|
||||||
|
```
|
||||||
|
function karatsuba (num1, num2)
|
||||||
|
if (num1 < 10) or (num2 < 10)
|
||||||
|
return num1 × num2 /* fall back to traditional multiplication */
|
||||||
|
|
||||||
|
/* Calculates the size of the numbers. */
|
||||||
|
m = min (size_base10(num1), size_base10(num2))
|
||||||
|
m2 = floor (m / 2)
|
||||||
|
/* m2 = ceil (m / 2) will also work */
|
||||||
|
|
||||||
|
/* Split the digit sequences in the middle. */
|
||||||
|
high1, low1 = split_at (num1, m2)
|
||||||
|
high2, low2 = split_at (num2, m2)
|
||||||
|
|
||||||
|
/* 3 recursive calls made to numbers approximately half the size. */
|
||||||
|
z0 = karatsuba (low1, low2)
|
||||||
|
z1 = karatsuba (low1 + high1, low2 + high2)
|
||||||
|
z2 = karatsuba (high1, high2)
|
||||||
|
|
||||||
|
return (z2 × 10 ^ (m2 × 2)) + ((z1 - z2 - z0) × 10 ^ m2) + z0
|
||||||
|
```
|
|
@ -1,24 +1,22 @@
|
||||||
def karatsuba(x, y):
|
def karatsuba(x, y):
|
||||||
xLen = len(str(x))
|
xLen = len(str(x))
|
||||||
yLen = len(str(y))
|
yLen = len(str(y))
|
||||||
# handle single digit multiplication at the end of the iteration
|
# fallback to traditional multiplication
|
||||||
# this gives the loop an end, and gives us our final results
|
|
||||||
if xLen == 1 or yLen == 1:
|
if xLen == 1 or yLen == 1:
|
||||||
return x * y
|
return x * y
|
||||||
else:
|
else:
|
||||||
n = max(xLen, yLen) // 2 # choose the longest length
|
n = max(xLen, yLen) // 2 # choose the largest size
|
||||||
# calculate a, b, c, d for the iteration
|
# split the digit sequences in the middle using some mathematical magic
|
||||||
a = x // (10 ** n)
|
low1 = x % (10 ** n)
|
||||||
b = x % (10 ** n)
|
low2 = y % (10 ** n)
|
||||||
c = y // (10 ** n)
|
high1 = x // (10 ** n)
|
||||||
d = y % (10 ** n)
|
high2 = y // (10 ** n)
|
||||||
# run karatsuba to resolve ac and bd for the iteration
|
# 3 recursive calls made to numbers approximately half the size
|
||||||
ac = karatsuba(a, c)
|
z0 = karatsuba(low1, low2)
|
||||||
bd = karatsuba(b, d)
|
z1 = karatsuba(low1 + high1, low2 + high2)
|
||||||
# use karatsuba again to resolve adbc for the iteration
|
z2 = karatsuba(high1, high2)
|
||||||
adbc = karatsuba(a + b, c + d) - ac - bd
|
# plug it into the formula
|
||||||
# return the solution for the digit pairs of the iteration
|
return (z2 * 10 ** (n * 2)) + ((z1 - z2 - z0) * (10 ** n)) + z0
|
||||||
return ac * 10 ** (2 * n) + (adbc * 10 ** n) + bd
|
|
||||||
|
|
||||||
# helper method to easily take in our inputs
|
# helper method to easily take in our inputs
|
||||||
def takeInput(text):
|
def takeInput(text):
|
||||||
|
|
34
python/calculators/readme.md
Normal file
34
python/calculators/readme.md
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
# calculators
|
||||||
|
|
||||||
|
Some extra information on the more complex topics (:
|
||||||
|
|
||||||
|
## Karatsuba's Algorithm
|
||||||
|
|
||||||
|
### Useful Links
|
||||||
|
|
||||||
|
- [Wikipedia](https://en.wikipedia.org/wiki/Karatsuba_algorithm)
|
||||||
|
- [An amazing video on the topic](https://youtu.be/cCKOl5li6YM)
|
||||||
|
|
||||||
|
### The Pseudocode
|
||||||
|
|
||||||
|
```
|
||||||
|
function karatsuba (num1, num2)
|
||||||
|
if (num1 < 10) or (num2 < 10)
|
||||||
|
return num1 × num2 /* fall back to traditional multiplication */
|
||||||
|
|
||||||
|
/* Calculates the size of the numbers. */
|
||||||
|
m = min (size_base10(num1), size_base10(num2))
|
||||||
|
m2 = floor (m / 2)
|
||||||
|
/* m2 = ceil (m / 2) will also work */
|
||||||
|
|
||||||
|
/* Split the digit sequences in the middle. */
|
||||||
|
high1, low1 = split_at (num1, m2)
|
||||||
|
high2, low2 = split_at (num2, m2)
|
||||||
|
|
||||||
|
/* 3 recursive calls made to numbers approximately half the size. */
|
||||||
|
z0 = karatsuba (low1, low2)
|
||||||
|
z1 = karatsuba (low1 + high1, low2 + high2)
|
||||||
|
z2 = karatsuba (high1, high2)
|
||||||
|
|
||||||
|
return (z2 × 10 ^ (m2 × 2)) + ((z1 - z2 - z0) × 10 ^ m2) + z0
|
||||||
|
```
|
Loading…
Reference in a new issue