#!/usr/bin/python

"""

"""

def add(a,b):
    assert a in range(10), "expect a number between 0 and 9 on a:"+str(a)
    assert b in range(10), "expect a number between 0 and 9 on b:"+str(b)
    return a+b

def sub(a,b):
    assert a in range(10), "expect a number between 0 and 9 on a:"+str(a)
    assert b in range(10), "expect a number between 0 and 9 on b:"+str(b)
    return a-b
   
def opTwoChar(a,b,op):
    """
    >>> opTwoChar('0','0',add)
    '0'
    >>> opTwoChar('2','3',add)
    '5'
    >>> opTwoChar('9','5',add)
    '14'
    """
    validChar = [ str(i) for i in range(-9,10) ]
    assert a in validChar, "character expected in a:"+str(a)
    assert b in validChar, "character expected in b:"+str(b)
    return str(op(int(a),int(b)))

def opTwoListChar(a,b,op):
    """
    >>> opTwoListChar(['3','2','1'],['1','2','3'],add)
    ['4', '4', '4']
    >>> opTwoListChar(['5','5','5'],['4','6','3'],add)
    ['9', '1', '9']
    >>> opTwoListChar(['9','9','9'],['2'],add)
    ['1', '0', '0', '1']
    >>> opTwoListChar(['5','5','5'],['6','6','6'],add)
    ['1', '2', '2', '1']
    """
    #zip truncate to smallest list
    la = len(a)
    lb = len(b)
    padding = ['0'] * ( max(la,lb) - min(la,lb) )
    a = a + padding
    b = b + padding
    ziped = zip(a,b)
    #expect list to pair of char to add
    result =  []
    remain = ['0']
    haveRemain = False
    for aa,bb in zip(a,b):
        if not aa:
            aa = '0'
        if not bb:
            bb = '0'
        cc = opTwoChar(aa,bb,op)
        neg = False
        if '-' == cc[0]:
            cc = cc[1:]
            neg = True
        if len(cc) == 1:
            remain.append('0')
        elif len(cc) == 2:
            remain.append(cc[0])
            haveRemain = True
            cc = cc[1]
        else:
            raise Exception("what the ?")
        if neg:
            cc = '-' + cc
        result.append(cc)
    finalresult = []
    if haveRemain:
        finalresult = opTwoListChar(result,remain,op)
    else:
        finalresult = result
    while finalresult[-1] == '0':
        finalresult = finalresult[:-1]
    return finalresult

def opTwoString(a,b,op):
    """
    >>> opTwoString('123','321',add)
    '444'
    >>> opTwoString('555','364',add)
    '919'
    >>> opTwoString('999','2',add)
    '1001'
    >>> opTwoString('555','666',add)
    '1221'
    >>> opTwoString('1000','1',sub)
    '999'
    >>> opTwoString('5','4',sub)
    '1'
    >>> opTwoString('3','4',sub)
    '-1'
    >>> opTwoString('321','123',sub)
    '298'
    """
    negA = False
    negB = False
    if a[0] == '-':
        a = a[1:]
        negA = True
    if b[0] == '-':
        b = b[1:]
        negB = True
    aa = list(a)    
    bb = list(b)
    if negA:
        aa = [ '-'+aaa for aaa in aa ]
    if negB: 
        bb = [ '-'+bbb for bbb in bb ]
    aa.reverse()
    bb.reverse()
    result = opTwoListChar(aa,bb,op)
    result.reverse()
    while result[0] == '0':
        result = result[1:]
    return "".join(result)

if __name__ == '__main__':
    import doctest
    doctest.testmod()
