diff --git a/multiplication/python/karatsuba.py b/multiplication/python/karatsuba.py index 00dd49a2..e117db47 100644 --- a/multiplication/python/karatsuba.py +++ b/multiplication/python/karatsuba.py @@ -1,4 +1,18 @@ +""" +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' @@ -8,7 +22,13 @@ def equalize_strings(x, y): x = zeros + x return x, y, len(x) -def sum(x, y): + +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 = '' @@ -25,7 +45,13 @@ def sum(x, y): result = '1' + result return result -def subtract(x, y): + +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 = "" @@ -50,7 +76,13 @@ def subtract(x, y): 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)) @@ -61,15 +93,17 @@ def kmul(x ,y): 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)) + ab_cd = kmul(add(a, b), add(c, d)) + ad_bc = absolute_difference(ab_cd, add(ac, bd)) zeros = "0" * (size - mid) - result = sum(ac + 2 * zeros, ad_bc + zeros) - result = sum(result, bd) + result = add(ac + 2 * zeros, ad_bc + zeros) + result = add(result, bd) result = result.lstrip('0') return result -x = "134231412" -y = "141324" -print(kmul(x, y)) + +if __name__ == "__main__": + x = "134231412" + y = "141324" + print(kmul(x, y))