From d3590720cf265569c70ab01e203ddef39709dbb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alim=20Kerem=20Erdo=C4=9Fmu=C5=9F?= Date: Mon, 24 Jan 2022 20:33:29 +0300 Subject: [PATCH] enh(Python): rename from karatsuba.py to karatsuba_algorithm.py (#670) --- algorithms/Python/README.md | 2 +- algorithms/Python/multiplication/karatsuba.py | 109 ----------------- .../multiplication/karatsuba_algorithm.py | 113 ++++++++++++++++++ 3 files changed, 114 insertions(+), 110 deletions(-) delete mode 100644 algorithms/Python/multiplication/karatsuba.py create mode 100644 algorithms/Python/multiplication/karatsuba_algorithm.py diff --git a/algorithms/Python/README.md b/algorithms/Python/README.md index 959198b4..1b6b1eac 100644 --- a/algorithms/Python/README.md +++ b/algorithms/Python/README.md @@ -15,7 +15,7 @@ - [Two Sum](dictionaries/two-sum.py) ## Multiplication -- [Karatsuba](multiplication/karatsuba.py) +- [Karatsuba](multiplication/karatsuba_algorithm.py) ## Recursion - [Factorial](recursion/factorial.py) diff --git a/algorithms/Python/multiplication/karatsuba.py b/algorithms/Python/multiplication/karatsuba.py deleted file mode 100644 index e117db47..00000000 --- a/algorithms/Python/multiplication/karatsuba.py +++ /dev/null @@ -1,109 +0,0 @@ -""" -https://en.wikipedia.org/wiki/Karatsuba_algorithm -""" - - -def equalize_strings(x, y): - """ - >>> def eq_str(x, y): - ... max_len = max(len(x), len(y)) - ... return x.zfill(max_len), y.zfill(max_len), max_len - >>> - >>> all(equalize_strings(x, y) == eq_str(x, y) for x, y - ... in (('x' * i, 'y' * (i // 2)) for i in range(10))) - True - """ - n = len(x) - m = len(y) - zeros = abs(n - m) * '0' - if n > m: - y = zeros + y - elif m > n: - x = zeros + x - return x, y, len(x) - - -def add(x, y): - """ - >>> all(add(str(x), str(y)) == str(x + y) for x, y - ... in ((0, 0), (0, 1), (1, 0), (1, 1234567890), (543210, 9876543))) - True - """ - x, y, size = equalize_strings(x, y) - carry = 0 - result = '' - for i in range(1, size+1): - # print(i) - dgt1 = int(x[size - i]) - dgt2 = int(y[size - i]) - dgt3 = (dgt1 + dgt2 + carry) % 10 - result = str(dgt3) + result - carry = int((dgt1 + dgt2 + carry) / 10) - # print(dgt1, dgt2, dgt3, result, carry) - - if carry: - result = '1' + result - return result - - -def absolute_difference(x, y): - """ - >>> all(absolute_difference(str(x), str(y)) == str(abs(x - y)) for x, y - ... in ((0, 0), (0, 1), (1, 0), (1, 1234567890), (543210, 9876543))) - True - """ - x, y, size = equalize_strings(x, y) - carry = 0 - result = "" - for i in range(size): - if y[i] < x[i]: - break - elif x[i] < y[i]: - tmp = x - x = y - y = tmp - break - - for i in range(1, size+1): - dgt1 = int(x[size - i]) - dgt2 = int(y[size - i]) - dgt3 = dgt1 - dgt2 - carry - if dgt3 < 0: - dgt3 += 10 - carry = 1 - else: - carry = 0 - result = str(dgt3) + result - return result - - -def kmul(x ,y): - """ - >>> all(kmul(str(x), str(y)) == str(x * y) for x, y - ... in ((0, 0), (0, 1), (1, 0), (1, 1234567890), (543210, 9876543))) - True - """ - x, y, size = equalize_strings(x, y) - if size == 1: - return str(int(x) * int(y)) - mid = int(size / 2) - a = x[:mid] - b = x[mid:] - c = y[:mid] - d = y[mid:] - ac = kmul(a, c) - bd = kmul(b, d) - ab_cd = kmul(add(a, b), add(c, d)) - ad_bc = absolute_difference(ab_cd, add(ac, bd)) - zeros = "0" * (size - mid) - - result = add(ac + 2 * zeros, ad_bc + zeros) - result = add(result, bd) - result = result.lstrip('0') - return result - - -if __name__ == "__main__": - x = "134231412" - y = "141324" - print(kmul(x, y)) diff --git a/algorithms/Python/multiplication/karatsuba_algorithm.py b/algorithms/Python/multiplication/karatsuba_algorithm.py new file mode 100644 index 00000000..56d08d89 --- /dev/null +++ b/algorithms/Python/multiplication/karatsuba_algorithm.py @@ -0,0 +1,113 @@ +""" +https://en.wikipedia.org/wiki/Karatsuba_algorithm +""" + + +def equalize_strings(x_value, y_value): + """ + >>> def eq_str(x, y): + ... max_len = max(len(x), len(y)) + ... return x.zfill(max_len), y.zfill(max_len), max_len + >>> + >>> all(equalize_strings(x, y) == eq_str(x, y) for x, y + ... in (('x' * i, 'y' * (i // 2)) for i in range(10))) + True + """ + n_value = len(x_value) + m_value = len(y_value) + zeros = abs(n_value - m_value) * '0' + if n_value > m_value: + y_value = zeros + y_value + elif m_value > n_value: + x_value = zeros + x_value + return x_value, y_value, len(x_value) + + +def add_function(x_value, y_value): + """ + >>> all(add_function(str(x), str(y)) == str(x + y) for x, y + ... in ((0, 0), (0, 1), (1, 0), (1, 1234567890), (543210, 9876543))) + True + """ + x_value, y_value, size = equalize_strings(x_value, y_value) + carry = 0 + result = '' + + for i in range(1, size+1): + # print(i) + dgt1 = int(x_value[size - i]) + dgt2 = int(y_value[size - i]) + dgt3 = (dgt1 + dgt2 + carry) % 10 + result = str(dgt3) + result + carry = int((dgt1 + dgt2 + carry) / 10) + # print(dgt1, dgt2, dgt3, result, carry) + + if carry: + result = '1' + result + + return result + + +def absolute_difference(x_value, y_value): + """ + >>> all(absolute_difference(str(x), str(y)) == str(abs(x - y)) for x, y + ... in ((0, 0), (0, 1), (1, 0), (1, 1234567890), (543210, 9876543))) + True + """ + x_value, y_value, size = equalize_strings(x_value, y_value) + carry = 0 + result = "" + + for i in range(size): + if y_value[i] <= x_value[i]: + break + #tmp = x_value + #x_value = y_value + #y_value = tmp + x_value, y_value = y_value, x_value + break + + for i in range(1, size+1): + dgt1 = int(x_value[size - i]) + dgt2 = int(y_value[size - i]) + dgt3 = dgt1 - dgt2 - carry + + if dgt3 < 0: + dgt3 += 10 + carry = 1 + else: + carry = 0 + result = str(dgt3) + result + + return result + + +def kmul_function(x_value ,y_value): + """ + >>> all(kmul_function(str(x), str(y)) == str(x * y) for x, y + ... in ((0, 0), (0, 1), (1, 0), (1, 1234567890), (543210, 9876543))) + True + """ + x_value, y_value, size = equalize_strings(x_value, y_value) + if size == 1: + return str(int(x_value) * int(y_value)) + + mid = int(size / 2) + a_value = x_value[:mid] + b_value = x_value[mid:] + c_value = y_value[:mid] + d_value = y_value[mid:] + ac_value = kmul_function(a_value, c_value) + bd_value = kmul_function(b_value, d_value) + ab_cd_value = kmul_function(add_function(a_value, b_value), add_function(c_value, d_value)) + ad_bc_value = absolute_difference(ab_cd_value, add_function(ac_value, bd_value)) + zeros = "0" * (size - mid) + result = add_function(ac_value + 2 * zeros, ad_bc_value + zeros) + result = add_function(result, bd_value) + result = result.lstrip('0') + return result + +if __name__ == "__main__": + X_VAR = "134231412" + Y_VAR = "141324" + print(kmul_function(X_VAR, Y_VAR))