What is the fastest way to sum two strings made up of only numbers but without converting each to an int beforehand?
Question:
If I am given two strings made up of only numbers 0-9, what is the fastest way to sum the two? Doing something like str(int(num1) + int(num2))
is not allowed and fails.
It mentions in a failed test that the max for an int() is 4300 characters:
ValueError: Exceeds the limit (4300) for integer string conversion: value has 2102288 digits; use sys.set_int_max_str_digits() to increase the limit
Each of the two strings of numbers can be 1,000,000+ characters/numbers long, be empty strings, have mismatched lengths, and/or have leading zeros.
The only way that I can think of is to add each top/bottom digit one at a time from right-to-left and carry the 1 over when necessary.
My version passes all of the tests but fails on long numbers.
def sum_strings(x, y):
if not x:
x = '0'
if not y:
y = '0'
x_len = len(x)
y_len = len(y)
if x_len > y_len:
y = y.rjust(x_len, '0')
elif y_len > x_len:
x = x.rjust(y_len, '0')
carry = 0
total = ''
for index in range(len(x) - 1, -1, -1):
new_sum = int(x[index]) + int(y[index]) + carry
if new_sum > 9:
new_sum -= 10
carry = 1
else:
carry = 0
total = f'{new_sum}{total}'
answer = f'{carry}{total}' if carry else total
return answer if len(answer) > 1 else answer.lstrip('0')
Times out:
Here are the example "easy" test cases.
@test.describe('Basic tests')
def test_examples():
@test.it('Example tests')
def basic_tests():
test.assert_equals(sum_strings("1", "1"), "2")
test.assert_equals(sum_strings("123", "456"), "579")
Is there any way to do it faster?
EDIT: Here is the updated/working version although now that I can see other submissions I think there are cleaner ways to do it than this:
def sum_strings(x, y):
if not x:
x = '0'
if not y:
y = '0'
x_len = len(x)
y_len = len(y)
if x_len > y_len:
y = y.rjust(x_len, '0')
elif y_len > x_len:
x = x.rjust(y_len, '0')
carry = 0
total = []
for index in range(len(x) - 1, -1, -1):
new_sum = int(x[index]) + int(y[index]) + carry
if new_sum > 9:
new_sum -= 10
carry = 1
else:
carry = 0
total.append(str(new_sum))
if carry:
total.append(str(carry))
total_str = ''.join(reversed(total))
return total_str[1:] if len(total_str) > 1 and total_str[0] == '0' else total_str
Answers:
Create a list of digits in the order you generate them, then create the final string using ''.join(reversed(digits))
.
If I am given two strings made up of only numbers 0-9, what is the fastest way to sum the two? Doing something like str(int(num1) + int(num2))
is not allowed and fails.
It mentions in a failed test that the max for an int() is 4300 characters:
ValueError: Exceeds the limit (4300) for integer string conversion: value has 2102288 digits; use sys.set_int_max_str_digits() to increase the limit
Each of the two strings of numbers can be 1,000,000+ characters/numbers long, be empty strings, have mismatched lengths, and/or have leading zeros.
The only way that I can think of is to add each top/bottom digit one at a time from right-to-left and carry the 1 over when necessary.
My version passes all of the tests but fails on long numbers.
def sum_strings(x, y):
if not x:
x = '0'
if not y:
y = '0'
x_len = len(x)
y_len = len(y)
if x_len > y_len:
y = y.rjust(x_len, '0')
elif y_len > x_len:
x = x.rjust(y_len, '0')
carry = 0
total = ''
for index in range(len(x) - 1, -1, -1):
new_sum = int(x[index]) + int(y[index]) + carry
if new_sum > 9:
new_sum -= 10
carry = 1
else:
carry = 0
total = f'{new_sum}{total}'
answer = f'{carry}{total}' if carry else total
return answer if len(answer) > 1 else answer.lstrip('0')
Times out:
Here are the example "easy" test cases.
@test.describe('Basic tests')
def test_examples():
@test.it('Example tests')
def basic_tests():
test.assert_equals(sum_strings("1", "1"), "2")
test.assert_equals(sum_strings("123", "456"), "579")
Is there any way to do it faster?
EDIT: Here is the updated/working version although now that I can see other submissions I think there are cleaner ways to do it than this:
def sum_strings(x, y):
if not x:
x = '0'
if not y:
y = '0'
x_len = len(x)
y_len = len(y)
if x_len > y_len:
y = y.rjust(x_len, '0')
elif y_len > x_len:
x = x.rjust(y_len, '0')
carry = 0
total = []
for index in range(len(x) - 1, -1, -1):
new_sum = int(x[index]) + int(y[index]) + carry
if new_sum > 9:
new_sum -= 10
carry = 1
else:
carry = 0
total.append(str(new_sum))
if carry:
total.append(str(carry))
total_str = ''.join(reversed(total))
return total_str[1:] if len(total_str) > 1 and total_str[0] == '0' else total_str
Create a list of digits in the order you generate them, then create the final string using ''.join(reversed(digits))
.