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
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