4

Lets say I have two numbers,

Number 1:

1646

Number 2:

2089

You see adding them left to right without the carry on adds up to 3625 how would I do this in python? I'm not sure but I need it to add 9+6 which is 15 but not to carry on the 1 when it adds 8+4 is there any way to add like this in python? And the end result i'm looking for is

3625

Since it doesn't carry on remaining numbers

John Y
  • 14,123
  • 2
  • 48
  • 72
ruler
  • 613
  • 1
  • 10
  • 17
  • you can try spliting the numbers by converting them to strings and adding them separately. – monkut Oct 08 '13 at 01:33
  • yes, but is their any more efficient way of doing this? – ruler Oct 08 '13 at 01:34
  • 4
    Does it matter if there is a more efficient way of doing it? Surely that would be the most legible, straightforward, and easy-to-understand way of doing it. – Waleed Khan Oct 08 '13 at 01:36
  • When you say efficient, do you mean *fast* or *fewest lines of code*? Because if you mean the first, is it really going to slow down your code? – SethMMorton Oct 08 '13 at 01:44
  • Hm, a little of both but I won't want a huge code to do this, roipii has that but I'm not sure how the zip works or what it's exactly doing – ruler Oct 08 '13 at 01:59

7 Answers7

8

This will work with varying N of integers of varying lengths:

from itertools import izip_longest

nums = [1646,
        2089,
         345]

revs = [str(n)[-1::-1] for n in nums]        # nums as reversed strings
izl  = izip_longest(*revs, fillvalue = '0')  # zip the digits together
xsum = lambda ds: str(sum(map(int, ds)))[-1] # digits -> last digit of their sum
rres = ''.join(xsum(ds) for ds in izl)       # result, but as reversed string
res  = int(rres[-1::-1])                     # result: 3960

Similar idea, but using map rather than izip_longest. I like this one better.

revs = [str(n)[-1::-1] for n in nums]           # nums as reversed strings
dsum = lambda *ds: sum(int(d or 0) for d in ds) # str-digits -> their sum
sums = map(dsum, *revs)[-1::-1]                 # digit sums, in order
ones = [str(s % 10) for s in sums]              # last digits of the sums
res  = int(''.join(ones))                       # result: 3960
FMc
  • 41,963
  • 13
  • 79
  • 132
4

Because I like to take poetic license with open-ended requests for 'more efficient':

In [49]: a,b = 1646,2089

In [50]: ''.join(str(sum(map(int,x)))[-1] for x in zip(str(a),str(b)))
Out[50]: '3625'
roippi
  • 25,533
  • 4
  • 48
  • 73
  • hm, that looks good but can you explain what the zip is doing? – ruler Oct 08 '13 at 01:55
  • 1
    @ruler you take 2 iterables and 'zip' them together (like a zipper) to make a number of 2-tuples equal to the length of the shortest iterable. But honestly this is more useful as code golf than anything else. Write your own function that does the above - albeit in more lines - that a human can actually read. Just because I managed to do it in one line does not make it 'pythonic'. – roippi Oct 08 '13 at 02:05
  • All respect to roppi, this is very clever ([golfy ;)](http://codegolf.stackexchange.com)) code, but @ruler its not code you should consider for production for the very reason that you aren't sure what its doing. It will fall down if the strings are different lengths. –  Oct 08 '13 at 02:13
  • @roipi can enumerate be used for this? – ruler Oct 08 '13 at 02:42
  • 1
    I think it's a bit clearer without the map: `int(''.join(str(int(a)+int(b))[-1] for a, b in izip(str(n1), str(n2))) )` – monkut Oct 08 '13 at 02:46
4

This will work even if the numbers of digits is not the same in both the numbers.

num1, num2, i, temp = 1646, 2089, 10, 0
total = num1 + num2
while num1 or num2:
    if (num1 % 10) + (num2 % 10) > 9: temp += i
    num1, num2, i = num1 // 10, num2 // 10, i * 10

print total - temp

Output

3625
thefourtheye
  • 233,700
  • 52
  • 457
  • 497
3

The following code demonstrates what you want, but please just consider this as a hint. The var names and lack of exception handling will jeopardize your real code.

import operator

n1 = 1646
n2 = 2089

l1 = [int(x) for x in str(n1)]
l2 = [int(x) for x in str(n2)]

res1 = map(operator.add, l1, l2)
res2 = [str(x)[-1] for x in res1]

num = "".join(res2)

print int(num)
shengy
  • 9,461
  • 4
  • 37
  • 61
1

This is kind of ugly because I do not know how to index a digit in an integer, only a string, but it works.

If the two strings are always the same size:

A = str(1646)
B = str(2089)
result = ""

for i in range(0,len(A)):
    result += str((int(A[i]) + int(B[i]))%10)

result = int(result)

If the two strings are not always the same size, find which one is bigger (length wise). Say the length of the biggest is X and the others length is Y where X > Y. Append the first X-Y indexes of the bigger string onto result, then repeat the above with the remaining digits.

Tommy
  • 12,588
  • 14
  • 59
  • 110
1

The numbers might be different length, so convert both to strings, reverse order (makes indexing easier), reverse using extended slice ([::-1], Reverse a string in Python), reverse back,

result=""
A=str(1646)[::-1]
B=str(2089)[::-1]
for ndx in range(0,max(len(A),len(B)):
    result += str(int(A[ndx])+int(B[ndx]))
resut = int(result[::-1])

You can get carry pretty easily, and handle unequal length strings (explicitly),

#!/bin/env python
a=1646
b=20893
A=str(a)[::-1]
B=str(b)[::-1]
lenA = len(A)
lenB = len(B)
length = max(lenA,lenB)
print "length: "+str(length)

#string add,no carry
total=""
for ndx in range(0,length):
    digit = 0
    if(ndx<lenA):
        digit += int(A[ndx])
    if(ndx<lenB):
        digit += int(B[ndx])
    digit = digit%10
    #print "digit: "+str(digit)+", carry: "+str(carry)
    total += str(digit)
print "a: " +str(a)+"+b: " +str(b)
result = total[::-1]
resut = int(result)
print "result: " +str(result)

#string add,with carry
total=""
carry=0
for ndx in range(0,length):
    digit = carry
    if(ndx<lenA):
        digit += int(A[ndx])
    if(ndx<lenB):
        digit += int(B[ndx])
    carry = digit/10
    digit = digit%10
    #print "digit: "+str(digit)+", carry: "+str(carry)
    total += str(digit)
if(carry>0):
    total += str(carry)
    #print "digit: "+str(digit)+", carry: "+str(carry)
print "a: " +str(a)+"+b: " +str(b)
result = total[::-1]
resut = int(result)
print "result: " +str(result)
Community
  • 1
  • 1
ChuckCottrill
  • 4,360
  • 2
  • 24
  • 42
1

First convert the numbers into strings so we can iterate over the digits:

>>> n1 = str(1646)
>>> n2 = str(2089)

We can then add the corresponding digits then do %10 to get the last digit. All numbers which result from adding two integers 0-9 will be <= 18, therefore %10 will always return the last digit.

>>> [(int(a)+int(b))%10 for a,b in zip(n1,n2)]
[3, 6, 2, 5]

We then convert each int into a string, join the digits and convert back to a int:

>>> int(''.join(map(str,((int(a)+int(b))%10 for a,b in zip(n1,n2)))))
3625

Or alternatively (converting the digits as you go):

>>> int(''.join(str((int(a)+int(b))%10) for a,b in zip(n1,n2)))
3625

Use izip_longest(...,fillvalue="0") to add numbers of different lengths.

HennyH
  • 7,794
  • 2
  • 29
  • 39