diff --git a/multiplication/README.md b/multiplication/README.md new file mode 100644 index 00000000..19370599 --- /dev/null +++ b/multiplication/README.md @@ -0,0 +1,9 @@ +# Multiplication algorithms + +### C or C++ + +1. [Karatsuba Multiplication](c-or-cpp/karatsuba.cpp) + +### Python + +1. [Karatsuba Multiplication](python/karatsuba.py) diff --git a/multiplication/c-or-cpp/karatsuba.cpp b/multiplication/c-or-cpp/karatsuba.cpp new file mode 100644 index 00000000..ecb8d0a5 --- /dev/null +++ b/multiplication/c-or-cpp/karatsuba.cpp @@ -0,0 +1,91 @@ +#include +#include +#include +using namespace std; + +int equalize_strings(string &x, string &y) { + int n = x.length(); + int m = y.length(); + string zeros(abs(n - m), '0'); + if (n > m) { + y = zeros + y; + } else if (m > n) { + x = zeros + x; + } + return x.length(); +} + +string sum(string x, string y) { + int len = equalize_strings(x, y); + int carry = 0; + string result; + for (int i = 1; i <= len; i++) { + int dgt1 = x[len - i] - '0'; + int dgt2 = y[len - i] - '0'; + int dgt3 = (dgt1 + dgt2 + carry) % 10; + result = to_string(dgt3) + result; + carry = (dgt1 + dgt2 + carry) / 10; + } + if (carry) { + result = '1' + result; + } + return result; +} + +string subtract(string x, string y) { + int len = equalize_strings(x, y); + int carry = 0; + string result; + for (int i = 0; i < len; i++) { + if (y[i] < x[i]) { + break; + } else if (x[i] < y[i]) { + string temp = x; + x = y; + y = temp; + break; + } + } + for (int i = 1; i <= len; i++) { + int dgt1 = x[len - i] - '0'; + int dgt2 = y[len - i] - '0'; + int dgt3 = dgt1 - dgt2 - carry; + if (dgt3 < 0) { + dgt3 += 10; + carry = 1; + } else { + carry = 0; + } + result = to_string(dgt3) + result; + } + return result; +} + +string kmul(string x, string y) { + int len = equalize_strings(x, y); + if(len == 1){ + return to_string((x[0]-'0') * (y[0]-'0')); + } + int mid = len / 2; + string a = x.substr(0, mid); + string b = x.substr(mid, len - mid); + string c = y.substr(0, mid); + string d = y.substr(mid, len - mid); + string ac = kmul(a, c); + string bd = kmul(b, d); + string ab_cd = kmul(sum(a, b), sum(c, d)); + string ad_bc = subtract(ab_cd, sum(ac,bd)); + string zeros(len - mid, '0'); + + string result = sum(ac + zeros + zeros, ad_bc + zeros); + result = sum(result, bd); + result.erase(0, min(result.find_first_not_of('0'), result.size()-1)); + return result; +} + +int main() { + string x, y; + cin >> x >> y; + cout << kmul(x, y) << endl; + return 0; +} diff --git a/multiplication/python/karatsuba.py b/multiplication/python/karatsuba.py new file mode 100644 index 00000000..00dd49a2 --- /dev/null +++ b/multiplication/python/karatsuba.py @@ -0,0 +1,75 @@ +def equalize_strings(x, y): + 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 sum(x, y): + 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 subtract(x, y): + 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): + 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(sum(a, b), sum(c, d)) + ad_bc = subtract(ab_cd, sum(ac, bd)) + zeros = "0" * (size - mid) + + result = sum(ac + 2 * zeros, ad_bc + zeros) + result = sum(result, bd) + result = result.lstrip('0') + return result + +x = "134231412" +y = "141324" +print(kmul(x, y))