|
| 1 | +""" |
| 2 | +Performs multiplication of two binary strings using the Karatsuba algorithm. |
| 3 | +
|
| 4 | +Given two binary strings of equal length n, the goal is to compute |
| 5 | +their product as integers. |
| 6 | +
|
| 7 | +For example: |
| 8 | +"1100" (12) × "1010" (10) = 120 |
| 9 | +
|
| 10 | +Karatsuba's algorithm reduces the multiplication of two n-bit numbers |
| 11 | +to at most three multiplications of n/2-bit numbers. It achieves |
| 12 | +a time complexity of O(n^log₂3) ≈ O(n^1.585), which is faster |
| 13 | +than the naive O(n²) approach. |
| 14 | +
|
| 15 | +References: |
| 16 | +https://en.wikipedia.org/wiki/Karatsuba_algorithm |
| 17 | +
|
| 18 | +Example: |
| 19 | +>>> karatsuba_multiply("1100", "1010") |
| 20 | +120 |
| 21 | +>>> karatsuba_multiply("10", "11") |
| 22 | +6 |
| 23 | +>>> karatsuba_multiply("101", "111") |
| 24 | +35 |
| 25 | +>>> karatsuba_multiply("0", "0") |
| 26 | +0 |
| 27 | +>>> karatsuba_multiply("1", "0") |
| 28 | +0 |
| 29 | +""" |
| 30 | + |
| 31 | +def karatsuba_multiply(x: str, y: str) -> int: |
| 32 | + """ |
| 33 | + Multiplies two binary strings using the Karatsuba algorithm. |
| 34 | +
|
| 35 | + Both input strings should be of equal length. |
| 36 | +
|
| 37 | + >>> karatsuba_multiply("1100", "1010") |
| 38 | + 120 |
| 39 | + >>> karatsuba_multiply("11", "10") |
| 40 | + 6 |
| 41 | + >>> karatsuba_multiply("1111", "1111") |
| 42 | + 225 |
| 43 | + """ |
| 44 | + n = max(len(x), len(y)) |
| 45 | + |
| 46 | + # Pad the shorter string with leading zeros |
| 47 | + x = x.zfill(n) |
| 48 | + y = y.zfill(n) |
| 49 | + |
| 50 | + # Base case: single bit multiplication |
| 51 | + if n == 1: |
| 52 | + return int(x) * int(y) |
| 53 | + |
| 54 | + mid = n // 2 |
| 55 | + |
| 56 | + # Split the binary strings into left and right halves |
| 57 | + x_left, x_right = x[:mid], x[mid:] |
| 58 | + y_left, y_right = y[:mid], y[mid:] |
| 59 | + |
| 60 | + # Recursively compute partial products |
| 61 | + p1 = karatsuba_multiply(x_left, y_left) |
| 62 | + p2 = karatsuba_multiply(x_right, y_right) |
| 63 | + p3 = karatsuba_multiply( |
| 64 | + bin(int(x_left, 2) + int(x_right, 2))[2:], |
| 65 | + bin(int(y_left, 2) + int(y_right, 2))[2:] |
| 66 | + ) |
| 67 | + |
| 68 | + # Karatsuba combination formula: |
| 69 | + result = (p1 << (2 * (n - mid))) + ((p3 - p1 - p2) << (n - mid)) + p2 |
| 70 | + |
| 71 | + return result |
| 72 | + |
| 73 | + |
| 74 | +if __name__ == "__main__": |
| 75 | + import doctest |
| 76 | + doctest.testmod() |
0 commit comments