1

Beginner here. I've spent most of the day working on the Karatsuba Algorithm just because I thought it would be fruitful. I've seen similar questions on here, but they are in other languages and seem strangely complex. The following is my code. The minute it hits the recursive call to ac, it just keeps on recursing. It's as if it never hits the base case. If anyone could be so kind as to offer some insight as to where things are going wrong, it would be greatly appreciated. For this code, you should assume I'm multiplying 2, base-10, four-digit numbers.

def karatsuba(x, y):
    if len(str(x)) == 1 or len(str(y)) == 1:
        return (x * y)

    else:
        n = (max(len(str(x)), len(str(y))))

        a = x / 10**(n / 2)
        b = x % 10**(n / 2)
        c = y / 10**(n / 2)
        d = y % 10**(n / 2)

        ac = karatsuba(a, c)
        ad = karatsuba(a, d)
        bc = karatsuba(b, c)
        bd = karatsuba(b, d)

        product = (10**n*(ac) + 10**(n/2)*(ad + bc) + bd)

        return product

print (karatsuba(1234, 5678))
7
  • the len of number will never be <1 - there is always at least 1 digit even if it is a 0 assume you meant ==1. If that is the case, any reason not to just test if they are <10 instead of converting to a str?
    – AChampion
    Commented Oct 8, 2016 at 2:32
  • @AChampion -- Thanks for the reply. Very good catch! I tried both methods. The == 1 approach left me with the same infinite recursion. The < 10 approach (with no typecasting to string) left me with a different infinite recursion on the "bc" line. The plot thickens. Thanks again!
    – Ryan
    Commented Oct 8, 2016 at 2:46
  • Is the issue indeterminate? I.e. are you finding different results each time your run it? Commented Oct 8, 2016 at 3:25
  • @sakurashinken I wish I were getting some result. I use IDLE for python, and I just get an endless stream of error pointing to a recursive line, right now it's ac. When I insert print statements, I saw a lot of decimalised values for a & c, that were unexpected.
    – Ryan
    Commented Oct 8, 2016 at 3:28
  • Assuming you are using python3. Use integer division // or you will introduce floats and cause issues. Tested with integer division and it works fine, though you can eliminate one of the recursive calls and much quicker would be operating in binary vs. decimal.
    – AChampion
    Commented Oct 8, 2016 at 3:42

2 Answers 2

3

Just fixing your code with integer divisions made it work correctly but here's a slight different version using 3 recursive calls (in base 10):

def karatsuba(x, y):
    if x < 10 or y < 10:
        return x * y

    n = max(len(str(x)), len(str(y))) // 2
    p = 10**n

    a, b = divmod(x, p)
    c, d = divmod(y, p)

    ac = karatsuba(a, c)
    bd = karatsuba(b, d)
    abcd = karatsuba(a+b, c+d) - ac - bd

    return (ac*p + abcd)*p + bd

But it is much faster operating in binary and using bit-twiddling:

def karatsuba(x, y):
    if x < 16 or y < 16:
        return x * y

    n = max(x.bit_length(), y.bit_length()) // 2
    mask = (1 << n) - 1

    a, b = x >> n, x & mask
    c, d = y >> n, y & mask

    ac = karatsuba(a, c)
    bd = karatsuba(b, d)
    abcd = karatsuba(a+b, c+d) - ac - bd

    return (((ac << n) + abcd) << n) + bd
3
  • 3
    (return (ac * p + abcd) * p + bd might be more readable and is closer to "the bit-twiddling variant".)
    – greybeard
    Commented Oct 8, 2016 at 7:38
  • Very impressive! Thanks for the help, guys. Lots to think about here!
    – Ryan
    Commented Oct 8, 2016 at 8:17
  • @greybeard very true - much neater
    – AChampion
    Commented Oct 8, 2016 at 13:57
1

Do you want integer division? In this case, you should use:

a = x // 10 ** (n / 2)

and

c = y // 10 ** (n / 2)

Otherwise, your program will be feeding through decimals to your function which I assume is not intended.

I'm also a beginner, feel free to correct me.

2
  • Many thanks for the reply! It made sense, so I gave it a shot. Unfortunately, the infinite recursion issue moved from the computation of ac to the recursive call for bd. Thanks again!
    – Ryan
    Commented Oct 8, 2016 at 3:21
  • 1
    @RyanD. You need to fix n//2 too - assuming you are using Python3. Which you also have in the final product calculation.
    – AChampion
    Commented Oct 8, 2016 at 3:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.