Search code examples
pythonpython-2.7radix

sum based on radix in Python 2.7


Working on a problem to calculate sum for any radix (radix between 2 to 10, inclusive), for example "10" + "20" based on 10 radix result in 30, and "10" + "20" based on radix 3 result in 100.

I post my code and test cases to verify it works, and my question is if any performance improvement or any ideas to make code more elegant (I have some repetitive code in my below implementation)? Thanks.

BTW, if code has any issues, please feel free to point out.

def radixSum(x, y, radix):

    if not x:
        return y
    if not y:
        return x

    # make x longer than y
    if (len(y) > len(x)):
        tmp = x
        x = y
        y = tmp
    lenCommon = min(len(x), len(y))
    count = 0
    remaining = 0
    i = -1
    result=''
    # deal with common part
    while count < lenCommon:
        value = int(x[i]) + int(y[i]) + remaining
        if value >= radix:
            remaining = 1
        else:
            remaining = 0
        if value >= radix:
            value = value - radix
        result = str(value) + result
        count += 1
        i -= 1

    # deal with longer string part
    while count < len(x):
        value = int(x[i]) + remaining
        if value >= radix:
            remaining = 1
        else:
            remaining = 0
        if value >= radix:
            value = value - radix
        result = str(value) + result
        count += 1
        i -= 1
    if remaining > 0:
        result = str(remaining) + result

    return result

if __name__ == "__main__":

    print radixSum("10", "10", 2) #100
    print radixSum("10", "20", 10) #30
    print radixSum("10", "20", 3) #100
    print radixSum("100", "20", 10) #120

Solution

  • Your code is mostly ok, but you repeat some tests unnecessarily. Instead of

    if value >= radix:
        remaining = 1
    else:
        remaining = 0
    if value >= radix:
        value = value - radix
    

    you can do

    if value >= radix:
        remaining = 1
        value = value - radix
    else:
        remaining = 0
    

    Another change you could make is to pad short numbers with zeroes so that you don't need to worry about handling extra digits in the longer number.

    FWIW, here's a more compact version. It uses itertools.izip_longest to simplify the process of adding corresponding digits and padding the shorter number with zeroes. I've also changed the function name so that it complies with the PEP-8 style guide.

    from itertools import izip_longest
    
    def radix_sum(x, y, radix):
        #add corresponding digits
        a = [int(u) + int(v) for u, v in izip_longest(x[::-1], y[::-1], fillvalue=0)]
        # normalize
        result = []
        carry = 0
        for u in a:
            carry, u = divmod(u + carry, radix)
            result.append(str(u))
        if carry:
            result.append(str(carry))
        return ''.join(result)[::-1]
    
    if __name__ == "__main__":
        print radix_sum("10", "10", 2) #100
        print radix_sum("10", "20", 10) #30
        print radix_sum("10", "20", 3) #100
        print radix_sum("100", "20", 10) #120
    

    output

    100
    30
    100
    120