From af1c6d8e1a822de8d1b3f0d860d9ac7a87fe126c Mon Sep 17 00:00:00 2001 From: Supratim <109270340+sgindeed@users.noreply.github.com> Date: Tue, 7 Oct 2025 09:46:59 +0530 Subject: [PATCH 1/5] Create karatsuba_multiplication.py --- .../karatsuba_multiplication.py | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 divide_and_conquer/karatsuba_multiplication.py diff --git a/divide_and_conquer/karatsuba_multiplication.py b/divide_and_conquer/karatsuba_multiplication.py new file mode 100644 index 000000000000..9500de47435f --- /dev/null +++ b/divide_and_conquer/karatsuba_multiplication.py @@ -0,0 +1,76 @@ +""" +Performs multiplication of two binary strings using the Karatsuba algorithm. + +Given two binary strings of equal length n, the goal is to compute +their product as integers. + +For example: +"1100" (12) × "1010" (10) = 120 + +Karatsuba's algorithm reduces the multiplication of two n-bit numbers +to at most three multiplications of n/2-bit numbers. It achieves +a time complexity of O(n^log₂3) ≈ O(n^1.585), which is faster +than the naive O(n²) approach. + +References: +https://en.wikipedia.org/wiki/Karatsuba_algorithm + +Example: +>>> karatsuba_multiply("1100", "1010") +120 +>>> karatsuba_multiply("10", "11") +6 +>>> karatsuba_multiply("101", "111") +35 +>>> karatsuba_multiply("0", "0") +0 +>>> karatsuba_multiply("1", "0") +0 +""" + +def karatsuba_multiply(x: str, y: str) -> int: + """ + Multiplies two binary strings using the Karatsuba algorithm. + + Both input strings should be of equal length. + + >>> karatsuba_multiply("1100", "1010") + 120 + >>> karatsuba_multiply("11", "10") + 6 + >>> karatsuba_multiply("1111", "1111") + 225 + """ + n = max(len(x), len(y)) + + # Pad the shorter string with leading zeros + x = x.zfill(n) + y = y.zfill(n) + + # Base case: single bit multiplication + if n == 1: + return int(x) * int(y) + + mid = n // 2 + + # Split the binary strings into left and right halves + x_left, x_right = x[:mid], x[mid:] + y_left, y_right = y[:mid], y[mid:] + + # Recursively compute partial products + p1 = karatsuba_multiply(x_left, y_left) + p2 = karatsuba_multiply(x_right, y_right) + p3 = karatsuba_multiply( + bin(int(x_left, 2) + int(x_right, 2))[2:], + bin(int(y_left, 2) + int(y_right, 2))[2:] + ) + + # Karatsuba combination formula: + result = (p1 << (2 * (n - mid))) + ((p3 - p1 - p2) << (n - mid)) + p2 + + return result + + +if __name__ == "__main__": + import doctest + doctest.testmod() From 07d94130948e2b747ef9389e33983a26355e5855 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 7 Oct 2025 04:17:50 +0000 Subject: [PATCH 2/5] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- divide_and_conquer/karatsuba_multiplication.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/divide_and_conquer/karatsuba_multiplication.py b/divide_and_conquer/karatsuba_multiplication.py index 9500de47435f..3cdd59692f90 100644 --- a/divide_and_conquer/karatsuba_multiplication.py +++ b/divide_and_conquer/karatsuba_multiplication.py @@ -28,6 +28,7 @@ 0 """ + def karatsuba_multiply(x: str, y: str) -> int: """ Multiplies two binary strings using the Karatsuba algorithm. @@ -62,7 +63,7 @@ def karatsuba_multiply(x: str, y: str) -> int: p2 = karatsuba_multiply(x_right, y_right) p3 = karatsuba_multiply( bin(int(x_left, 2) + int(x_right, 2))[2:], - bin(int(y_left, 2) + int(y_right, 2))[2:] + bin(int(y_left, 2) + int(y_right, 2))[2:], ) # Karatsuba combination formula: @@ -73,4 +74,5 @@ def karatsuba_multiply(x: str, y: str) -> int: if __name__ == "__main__": import doctest + doctest.testmod() From 95ae788408b338ecd9af701b2e032fff8b9588ea Mon Sep 17 00:00:00 2001 From: Supratim <109270340+sgindeed@users.noreply.github.com> Date: Tue, 7 Oct 2025 09:48:52 +0530 Subject: [PATCH 3/5] Update karatsuba_multiplication.py --- .../karatsuba_multiplication.py | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/divide_and_conquer/karatsuba_multiplication.py b/divide_and_conquer/karatsuba_multiplication.py index 3cdd59692f90..80600d193d0f 100644 --- a/divide_and_conquer/karatsuba_multiplication.py +++ b/divide_and_conquer/karatsuba_multiplication.py @@ -28,8 +28,7 @@ 0 """ - -def karatsuba_multiply(x: str, y: str) -> int: +def karatsuba_multiply(binary_str_1: str, binary_str_2: str) -> int: """ Multiplies two binary strings using the Karatsuba algorithm. @@ -42,37 +41,38 @@ def karatsuba_multiply(x: str, y: str) -> int: >>> karatsuba_multiply("1111", "1111") 225 """ - n = max(len(x), len(y)) + n = max(len(binary_str_1), len(binary_str_2)) # Pad the shorter string with leading zeros - x = x.zfill(n) - y = y.zfill(n) + binary_str_1 = binary_str_1.zfill(n) + binary_str_2 = binary_str_2.zfill(n) # Base case: single bit multiplication if n == 1: - return int(x) * int(y) + return int(binary_str_1) * int(binary_str_2) mid = n // 2 # Split the binary strings into left and right halves - x_left, x_right = x[:mid], x[mid:] - y_left, y_right = y[:mid], y[mid:] + left_1, right_1 = binary_str_1[:mid], binary_str_1[mid:] + left_2, right_2 = binary_str_2[:mid], binary_str_2[mid:] # Recursively compute partial products - p1 = karatsuba_multiply(x_left, y_left) - p2 = karatsuba_multiply(x_right, y_right) - p3 = karatsuba_multiply( - bin(int(x_left, 2) + int(x_right, 2))[2:], - bin(int(y_left, 2) + int(y_right, 2))[2:], + product_left = karatsuba_multiply(left_1, left_2) + product_right = karatsuba_multiply(right_1, right_2) + product_sum = karatsuba_multiply( + bin(int(left_1, 2) + int(right_1, 2))[2:], + bin(int(left_2, 2) + int(right_2, 2))[2:] ) - # Karatsuba combination formula: - result = (p1 << (2 * (n - mid))) + ((p3 - p1 - p2) << (n - mid)) + p2 + # Karatsuba combination formula + result = (product_left << (2 * (n - mid))) + ( + (product_sum - product_left - product_right) << (n - mid) + ) + product_right return result if __name__ == "__main__": import doctest - doctest.testmod() From 6b69ea23d2d006a116fdca73fe49c20fc45caa91 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 7 Oct 2025 04:19:59 +0000 Subject: [PATCH 4/5] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- divide_and_conquer/karatsuba_multiplication.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/divide_and_conquer/karatsuba_multiplication.py b/divide_and_conquer/karatsuba_multiplication.py index 80600d193d0f..19450773fe52 100644 --- a/divide_and_conquer/karatsuba_multiplication.py +++ b/divide_and_conquer/karatsuba_multiplication.py @@ -28,6 +28,7 @@ 0 """ + def karatsuba_multiply(binary_str_1: str, binary_str_2: str) -> int: """ Multiplies two binary strings using the Karatsuba algorithm. @@ -62,17 +63,20 @@ def karatsuba_multiply(binary_str_1: str, binary_str_2: str) -> int: product_right = karatsuba_multiply(right_1, right_2) product_sum = karatsuba_multiply( bin(int(left_1, 2) + int(right_1, 2))[2:], - bin(int(left_2, 2) + int(right_2, 2))[2:] + bin(int(left_2, 2) + int(right_2, 2))[2:], ) # Karatsuba combination formula - result = (product_left << (2 * (n - mid))) + ( - (product_sum - product_left - product_right) << (n - mid) - ) + product_right + result = ( + (product_left << (2 * (n - mid))) + + ((product_sum - product_left - product_right) << (n - mid)) + + product_right + ) return result if __name__ == "__main__": import doctest + doctest.testmod() From f1a39147f23e23da90549b588f49446812e7352b Mon Sep 17 00:00:00 2001 From: Supratim <109270340+sgindeed@users.noreply.github.com> Date: Tue, 7 Oct 2025 09:51:31 +0530 Subject: [PATCH 5/5] Update karatsuba_multiplication.py --- .../karatsuba_multiplication.py | 115 +++++++----------- 1 file changed, 47 insertions(+), 68 deletions(-) diff --git a/divide_and_conquer/karatsuba_multiplication.py b/divide_and_conquer/karatsuba_multiplication.py index 19450773fe52..b156d38e8e85 100644 --- a/divide_and_conquer/karatsuba_multiplication.py +++ b/divide_and_conquer/karatsuba_multiplication.py @@ -1,79 +1,58 @@ """ -Performs multiplication of two binary strings using the Karatsuba algorithm. - -Given two binary strings of equal length n, the goal is to compute -their product as integers. - -For example: -"1100" (12) × "1010" (10) = 120 - -Karatsuba's algorithm reduces the multiplication of two n-bit numbers -to at most three multiplications of n/2-bit numbers. It achieves -a time complexity of O(n^log₂3) ≈ O(n^1.585), which is faster -than the naive O(n²) approach. - -References: -https://en.wikipedia.org/wiki/Karatsuba_algorithm +Karatsuba Multiplication Algorithm +---------------------------------- +Given two binary strings that represent the value of two integers, +find the product of the two strings using the Karatsuba algorithm. Example: ->>> karatsuba_multiply("1100", "1010") -120 ->>> karatsuba_multiply("10", "11") -6 ->>> karatsuba_multiply("101", "111") -35 ->>> karatsuba_multiply("0", "0") -0 ->>> karatsuba_multiply("1", "0") -0 + "1100" (12) x "1010" (10) = 120 """ -def karatsuba_multiply(binary_str_1: str, binary_str_2: str) -> int: +def karatsuba_multiply(bin_num1: str, bin_num2: str) -> int: """ - Multiplies two binary strings using the Karatsuba algorithm. - - Both input strings should be of equal length. - - >>> karatsuba_multiply("1100", "1010") - 120 - >>> karatsuba_multiply("11", "10") - 6 - >>> karatsuba_multiply("1111", "1111") - 225 + Multiply two binary strings using the Karatsuba algorithm. + + Args: + bin_num1 (str): The first binary string. + bin_num2 (str): The second binary string. + + Returns: + int: The product of the two binary strings as an integer. + + Examples: + >>> karatsuba_multiply("1100", "1010") + 120 + >>> karatsuba_multiply("11", "11") + 9 + >>> karatsuba_multiply("101", "10") + 10 """ - n = max(len(binary_str_1), len(binary_str_2)) - - # Pad the shorter string with leading zeros - binary_str_1 = binary_str_1.zfill(n) - binary_str_2 = binary_str_2.zfill(n) - - # Base case: single bit multiplication - if n == 1: - return int(binary_str_1) * int(binary_str_2) - - mid = n // 2 - - # Split the binary strings into left and right halves - left_1, right_1 = binary_str_1[:mid], binary_str_1[mid:] - left_2, right_2 = binary_str_2[:mid], binary_str_2[mid:] - - # Recursively compute partial products - product_left = karatsuba_multiply(left_1, left_2) - product_right = karatsuba_multiply(right_1, right_2) - product_sum = karatsuba_multiply( - bin(int(left_1, 2) + int(right_1, 2))[2:], - bin(int(left_2, 2) + int(right_2, 2))[2:], - ) - - # Karatsuba combination formula - result = ( - (product_left << (2 * (n - mid))) - + ((product_sum - product_left - product_right) << (n - mid)) - + product_right - ) - - return result + # Convert binary strings to integers + x = int(bin_num1, 2) + y = int(bin_num2, 2) + + # Base case for recursion + if x < 2 or y < 2: + return x * y + + # Calculate the size of the numbers + n = max(len(bin_num1), len(bin_num2)) + half = n // 2 + + # Split the binary strings + x_high = x >> half + x_low = x & ((1 << half) - 1) + y_high = y >> half + y_low = y & ((1 << half) - 1) + + # Recursive multiplications + a = karatsuba_multiply(bin(x_high)[2:], bin(y_high)[2:]) + d = karatsuba_multiply(bin(x_low)[2:], bin(y_low)[2:]) + e = karatsuba_multiply(bin(x_high + x_low)[2:], bin(y_high + y_low)[2:]) - a - d + + # Combine results + return (a << (2 * half)) + (e << half) + d if __name__ == "__main__":