Given a mathematical expression, solve it.
input: a-(b+c+b)
output: a-2b-c
input: -(a-(b+c+b)-d-(-(e-b)-d))
output: -a+3b+c-e
TC: O(n*n) + O(n) ~> Stack worst case + dict
SC: O(n*n) ~> Stack and dict
import collections
def sign_converter(sign):
    return "+" if sign == "-" else "-"
def change_sign(expr: str):
    new_subs = ""
    
    if expr[0].isalpha():
        new_subs += "-"
    
    for each in expr:
        if each in ("+", "-"):
            new_subs += sign_converter(each)
        else:
            new_subs += each
    return new_subs
def convert_dict_to_short_string(d):
    res = ""
    for each in d:
        if d[each] == 0:
            continue
        if d[each] < 0:
            if d[each] < -1:
                res += str(d[each]) + each
            else:
                res += "-" + each
        else:
            if d[each] > 1:
                res += "+" + str(d[each]) + each
            else:
                res += "+" + each
    if res[0] == "+":
        return res[1:]
    
    return res
def compress_str(expr_arr):
    d = collections.defaultdict(int)
    for i in range(1, len(expr_arr), 2):
        if expr_arr[i-1] == "+":
            d[expr_arr[i]] += 1
        else:
            d[expr_arr[i]] -= 1
    
    return convert_dict_to_short_string(d)
    
def calculate_expression(expression):
    if expression[0].isalpha():
        expression = "+" + expression
    stack, i = [], 0
    while i < len(expression):
        if expression[i] != ")":
            stack.append(expression[i])
        
        elif expression[i] == ")":
            curr_sub_string = ""
            
            while stack[-1] != "(":
                curr_sub_string += stack.pop()
            curr_sub_string = curr_sub_string[::-1]
            stack.pop()
            if stack and stack[-1] == "-":
                curr_sub_string = change_sign(curr_sub_string)
            
            if curr_sub_string[0].isalpha():
                curr_sub_string = "+" + curr_sub_string
            if stack:
                stack.pop()
            stack += list(curr_sub_string)
        i += 1
    return "".join(stack)
if __name__ == "__main__":
    string = "-(a-(b+c+b)-d-(-(e-b)-d))"
    eval_expr = calculate_expression(string)
    shortened_expr = compress_str(eval_expr)
    print(shortened_expr)