#!/usr/bin/python3

import sys
from typing import Sequence
from unittest import result
import numpy
import time

def overlap(arg1: str, arg2: str) -> str:
    overlap_result = ''
    arg1_as_string = str(arg1)
    arg1_integer_part = arg1_as_string
    arg1_decimal_part = ''
    arg1_is_full_integer = True
    arg1_is_negative = True if arg1_integer_part.startswith('-') else False
    try:
        arg1_integer_part, arg1_decimal_part = arg1_as_string.split(".")
        if arg1_decimal_part==len(arg1_decimal_part)*'0': arg1_is_full_integer = True
        else: arg1_is_full_integer = False
    except:
        pass#nothing to do
    if arg1_is_negative: arg1_integer_part = arg1_integer_part.replace('-', '')
    # transform arg2 to string if not already in string and test if it's a full integer (without decimal part or decimal part equals zero)
    arg2_as_string = str(arg2)
    arg2_integer_part = arg2_as_string
    arg2_decimal_part = ''
    arg2_is_full_integer = True
    arg2_is_negative = True if arg2_integer_part.startswith('-') else False
    try:
        arg2_integer_part, arg2_decimal_part = arg2_as_string.split(".")
        if arg2_decimal_part==len(arg2_decimal_part)*'0': arg2_is_full_integer = True
        else: arg2_is_full_integer = False
    except:
        pass#nothing to do
    if arg2_is_negative: arg2_integer_part = arg2_integer_part.replace('-', '')
    # making integer and decimal parts same size
    max_integer_part_size = max( len(arg1_integer_part), len(arg2_integer_part) )
    arg1_integer_part = '0'*(max_integer_part_size-len(arg1_integer_part)) + arg1_integer_part
    arg2_integer_part = '0'*(max_integer_part_size-len(arg2_integer_part)) + arg2_integer_part
    #---------
    max_decimal_part_size = max(len(arg1_decimal_part),len(arg2_decimal_part))
    arg1_decimal_part = arg1_decimal_part + '0'*(max_decimal_part_size-len(arg1_decimal_part))
    arg2_decimal_part = arg2_decimal_part + '0'*(max_decimal_part_size-len(arg2_decimal_part))
    #---------
    if not(arg1_is_negative) and arg2_is_negative: #arg1 positive - arg2 negative
        overlap_result += "1"
    elif not(arg1_is_negative) and not(arg2_is_negative): #arg1 positive - arg2 positive
        overlap_result += "2"
    elif arg1_is_negative and not(arg2_is_negative): #arg1 negative - arg2 positive
        overlap_result += "3"
    elif arg1_is_negative and arg2_is_negative: #arg1 negative - arg2 negative
        overlap_result += "4"
    #---------
    for index in range(max_integer_part_size):
        overlap_result += arg1_integer_part[index]
        overlap_result += arg2_integer_part[index]
    if not(arg1_is_full_integer) or not(arg2_is_full_integer): overlap_result += "."
    for index in range(max_decimal_part_size):
        overlap_result += arg1_decimal_part[index]
        overlap_result += arg2_decimal_part[index]
    return overlap_result


def unoverlap(arg: str) -> Sequence[str]:
    arg1 = '' #for stocking unoverlapped values
    arg2 = ''
    arg_as_string = str(arg)
    arg_is_full_integer = True
    try:
        arg_integer_part, arg_decimal_part = arg_as_string.split(".")
        if arg_decimal_part==len(arg_decimal_part)*'0': arg_is_full_integer = True
        else: arg_is_full_integer = False
    except:
        pass#nothing to do
    if arg_integer_part[0]=="1": #arg1 must be positive - arg2 must be negative
        arg2 += '-'
    elif arg_integer_part[0]=="2": #arg1 must be positive - arg2 must be positive
        pass
    elif arg_integer_part[0]=="3": #arg1 must be negative - arg2 must be positive
        arg1 += '-'
    elif arg_integer_part[0]=="4": #arg1 must be negative - arg2 must be negative
        arg1 += '-'
        arg2 += '-'
    arg_integer_part = arg_integer_part[1:] #ignoring signs' digit now as it's already used
    for index in range(len(arg_integer_part)):
        if index%2==0: arg1 += arg_integer_part[index]
        else: arg2 += arg_integer_part[index]
    if not(arg_is_full_integer):
        arg1 += '.'
        arg2 += '.'
        for index in range(len(arg_decimal_part)):
            if index%2==0: arg1 += arg_decimal_part[index]
            else: arg2 += arg_decimal_part[index]
    arg1 = good_format(arg1)
    arg2 = good_format(arg2)
    return arg1, arg2


def sb_addition(arg1: str, arg2: str) -> str:
    result = ''
    # the addition will be a substraction if (arg1 is negative and arg2 is positive) or (arg1 is positive and arg2 is negative)
    if str(arg1).startswith('-') and not(str(arg2).startswith('-')): # arg1 is negative and arg2 is positive
        return sb_substract(str(arg2), str(arg1).replace('-',''))
    elif not(str(arg1).startswith('-')) and str(arg2).startswith('-'): # arg1 is positive and arg2 is negative
        return sb_substract(str(arg1), str(arg2).replace('-',''))
    # transform arg1 to string if not already in string and test if it's a full integer (without decimal part or decimal part equals zero)
    arg1_as_string = str(arg1)
    arg1_integer_part = arg1_as_string
    arg1_decimal_part = ''
    arg1_is_full_integer = True
    arg1_is_negative = True if arg1_integer_part.startswith('-') else False
    try:
        arg1_integer_part, arg1_decimal_part = arg1_as_string.split(".")
        if arg1_decimal_part==len(arg1_decimal_part)*'0': arg1_is_full_integer = True
        else: arg1_is_full_integer = False
    except:
        pass#nothing to do
    if arg1_is_negative: arg1_integer_part = arg1_integer_part.replace('-', '')
    # transform arg2 to string if not already in string and test if it's a full integer (without decimal part or decimal part equals zero)
    arg2_as_string = str(arg2)
    arg2_integer_part = arg2_as_string
    arg2_decimal_part = ''
    arg2_is_full_integer = True
    arg2_is_negative = True if arg2_integer_part.startswith('-') else False
    try:
        arg2_integer_part, arg2_decimal_part = arg2_as_string.split(".")
        if arg2_decimal_part==len(arg2_decimal_part)*'0': arg2_is_full_integer = True
        else: arg2_is_full_integer = False
    except:
        pass#nothing to do
    if arg2_is_negative: arg2_integer_part = arg2_integer_part.replace('-', '')
    # making integer and decimal parts same size
    max_integer_part_size = max( len(arg1_integer_part), len(arg2_integer_part) )
    arg1_integer_part = '0'*(max_integer_part_size-len(arg1_integer_part)) + arg1_integer_part
    arg2_integer_part = '0'*(max_integer_part_size-len(arg2_integer_part)) + arg2_integer_part
    #---------
    max_decimal_part_size = max(len(arg1_decimal_part),len(arg2_decimal_part))
    arg1_decimal_part = arg1_decimal_part + '0'*(max_decimal_part_size-len(arg1_decimal_part))
    arg2_decimal_part = arg2_decimal_part + '0'*(max_decimal_part_size-len(arg2_decimal_part))
    # making real addition operation
    # when here, it means both numbers are positives OR both numbers are negatives
    rem = '0'
    if not(arg1_is_full_integer) or not(arg2_is_full_integer):
        for i in range(max_decimal_part_size-1, -1, -1):
            res = int( eval('(' + arg1_decimal_part[i] + '+' + arg2_decimal_part[i] + '+' + str(rem) + ')%10') )
            result = str(res) + result
            rem = int( eval('((' + arg1_decimal_part[i] + '+' + arg2_decimal_part[i] + '+' + str(rem) + ') - ' + str(res) + ')/10') )
        result = '.' + result
    for i in range(max_integer_part_size-1, -1, -1):
        res = int( eval('(' + arg1_integer_part[i] + '+' + arg2_integer_part[i] + '+' + str(rem) + ')%10') )
        result = str(res) + result
        rem = int( eval('((' + arg1_integer_part[i] + '+' + arg2_integer_part[i] + '+' + str(rem) + ') - ' + str(res) + ')/10') )
    if str(rem) != '0': result = str(rem) + result
    if arg1_is_negative and arg2_is_negative: result = '-' + result # treat the case both numbers are negative
    result = good_format(result)
    return result


def sb_substract(arg1: str, arg2: str) -> str:
    result = '' # will be arg1-arg2
    # the substraction will be an addition if (arg1 is negative and arg2 is positive) or (arg1 is positive and arg2 is negative)
    if str(arg1).startswith('-') and not(str(arg2).startswith('-')): # arg1 is negative and arg2 is positive
        return sb_addition(str(arg1), '-'+str(arg2))
    elif not(str(arg1).startswith('-')) and str(arg2).startswith('-'): # arg1 is positive and arg2 is negative
        return sb_addition(str(arg1), str(arg2).replace('-',''))
    # transform arg1 to string if not already in string and test if it's a full integer (without decimal part or decimal part equals zero)
    arg1_as_string = str(arg1)
    arg1_integer_part = arg1_as_string
    arg1_decimal_part = ''
    arg1_is_full_integer = True
    arg1_is_negative = True if arg1_integer_part.startswith('-') else False
    try:
        arg1_integer_part, arg1_decimal_part = arg1_as_string.split(".")
        if arg1_decimal_part==len(arg1_decimal_part)*'0': arg1_is_full_integer = True
        else: arg1_is_full_integer = False
    except:
        pass#nothing to do
    if arg1_is_negative: arg1_integer_part = arg1_integer_part.replace('-', '')
    # transform arg2 to string if not already in string and test if it's a full integer (without decimal part or decimal part equals zero)
    arg2_as_string = str(arg2)
    arg2_integer_part = arg2_as_string
    arg2_decimal_part = ''
    arg2_is_full_integer = True
    arg2_is_negative = True if arg2_integer_part.startswith('-') else False
    try:
        arg2_integer_part, arg2_decimal_part = arg2_as_string.split(".")
        if arg2_decimal_part==len(arg2_decimal_part)*'0': arg2_is_full_integer = True
        else: arg2_is_full_integer = False
    except:
        pass#nothing to do
    if arg2_is_negative: arg2_integer_part = arg2_integer_part.replace('-', '')
    # making integer and decimal parts same size
    max_integer_part_size = max( len(arg1_integer_part), len(arg2_integer_part) )
    arg1_integer_part = '0'*(max_integer_part_size-len(arg1_integer_part)) + arg1_integer_part
    arg2_integer_part = '0'*(max_integer_part_size-len(arg2_integer_part)) + arg2_integer_part
    #---------
    max_decimal_part_size = max(len(arg1_decimal_part),len(arg2_decimal_part))
    arg1_decimal_part = arg1_decimal_part + '0'*(max_decimal_part_size-len(arg1_decimal_part))
    arg2_decimal_part = arg2_decimal_part + '0'*(max_decimal_part_size-len(arg2_decimal_part))
    # making real substraction operation
    # when here, it means both numbers are positives OR both numbers are negatives
    result_needs_negative_sign_in_font = False
    if arg1_is_negative and arg2_is_negative:
        if eval( 'abs('+arg2 + ')>=abs(' + arg1 + ')' ):
            temp = arg1_integer_part
            arg1_integer_part = arg2_integer_part
            arg2_integer_part = temp
            #---------
            temp = arg1_decimal_part
            arg1_decimal_part = arg2_decimal_part
            arg2_decimal_part = temp
        else:
            result_needs_negative_sign_in_font = True
    elif not(arg1_is_negative) and not(arg2_is_negative):
        if eval( 'abs('+arg1 + ')>=abs(' + arg2 + ')' ):
            pass # nothing to do
        else:
            temp = arg1_integer_part
            arg1_integer_part = arg2_integer_part
            arg2_integer_part = temp
            #---------
            temp = arg1_decimal_part
            arg1_decimal_part = arg2_decimal_part
            arg2_decimal_part = temp
            result_needs_negative_sign_in_font = True
    rem = '0'
    if not(arg1_is_full_integer) or not(arg2_is_full_integer):
        for i in range(max_decimal_part_size-1, -1, -1):
            upper_digit_to_consider = int( eval( arg1_decimal_part[i] + '+' + '10 if ' + arg1_decimal_part[i] + '<(' + arg2_decimal_part[i] + '+' + str(rem) + ') else ' + arg1_decimal_part[i] ) )
            res = int( eval( str(upper_digit_to_consider) + '-(' + arg2_decimal_part[i] + '+' + str(rem) + ')' ) )
            result = str(res) + result
            rem = int( eval( '1 if ' + arg1_decimal_part[i] + '<(' + arg2_decimal_part[i] + '+' + str(rem) + ') else 0' ) )
        result = '.' + result
    for i in range(max_integer_part_size-1, -1, -1):
        upper_digit_to_consider = int( eval( arg1_integer_part[i] + '+' + '10 if ' + arg1_integer_part[i] + '<(' + arg2_integer_part[i] + '+' + str(rem) + ') else ' + arg1_integer_part[i] ) )
        res = int( eval( str(upper_digit_to_consider) + '-(' + arg2_integer_part[i] + '+' + str(rem) + ')' ) )
        result = str(res) + result
        rem = int( eval( '1 if ' + arg1_integer_part[i] + '<(' + arg2_integer_part[i] + '+' + str(rem) + ') else 0' ) )
    if str(rem) != '0': result = str(rem) + result
    if result_needs_negative_sign_in_font: result = '-' + result
    result = good_format(result)
    return result


def sb_multiply(arg1: str, arg2: str) -> bool:
    # transform arg1 to string if not already in string and test if it's a full integer (without decimal part or decimal part equals zero)
    arg1_as_string = str(arg1)
    arg1_integer_part = arg1_as_string
    arg1_decimal_part = ''
    arg1_is_full_integer = True
    arg1_is_negative = True if arg1_integer_part.startswith('-') else False
    try:
        arg1_integer_part, arg1_decimal_part = arg1_as_string.split(".")
        if arg1_decimal_part==len(arg1_decimal_part)*'0': arg1_is_full_integer = True
        else: arg1_is_full_integer = False
    except:
        pass#nothing to do
    if arg1_is_negative: arg1_integer_part = arg1_integer_part.replace('-', '')
    # transform arg2 to string if not already in string and test if it's a full integer (without decimal part or decimal part equals zero)
    arg2_as_string = str(arg2)
    arg2_integer_part = arg2_as_string
    arg2_decimal_part = ''
    arg2_is_full_integer = True
    arg2_is_negative = True if arg2_integer_part.startswith('-') else False
    try:
        arg2_integer_part, arg2_decimal_part = arg2_as_string.split(".")
        if arg2_decimal_part==len(arg2_decimal_part)*'0': arg2_is_full_integer = True
        else: arg2_is_full_integer = False
    except:
        pass#nothing to do
    if arg2_is_negative: arg2_integer_part = arg2_integer_part.replace('-', '')
    # making integer and decimal parts same size
    max_integer_part_size = max( len(arg1_integer_part), len(arg2_integer_part) )
    arg1_integer_part = '0'*(max_integer_part_size-len(arg1_integer_part)) + arg1_integer_part
    arg2_integer_part = '0'*(max_integer_part_size-len(arg2_integer_part)) + arg2_integer_part
    #---------
    max_decimal_part_size = max(len(arg1_decimal_part),len(arg2_decimal_part))
    arg1_decimal_part = arg1_decimal_part + '0'*(max_decimal_part_size-len(arg1_decimal_part))
    arg2_decimal_part = arg2_decimal_part + '0'*(max_decimal_part_size-len(arg2_decimal_part))
    # making real multiplication operation
    rem = '0'
    intermediate_numbers = []
    if arg2_is_full_integer:
        down_number_in_multiplication = arg2_integer_part
    else:
        down_number_in_multiplication = arg2_integer_part+arg2_decimal_part
    if arg1_is_full_integer:
        up_number_in_multiplication = arg1_integer_part
    else:
        up_number_in_multiplication = arg1_integer_part+arg1_decimal_part
    #----------------
    for j in range(len(down_number_in_multiplication)-1, -1, -1):
        current_intermediate_number = '0'*( (len(down_number_in_multiplication)-1) - j )
        for i in range(len(up_number_in_multiplication)-1, -1, -1):
            res = int( eval( '((' + down_number_in_multiplication[j] + '*' + up_number_in_multiplication[i] + ')+' + str(rem) + ')%10' ) )
            current_intermediate_number = str(res) + current_intermediate_number
            rem = int( eval( '(((' + down_number_in_multiplication[j] + '*' + up_number_in_multiplication[i] + ')+' + str(rem) + ') - ' + str(res) + ')/10') )
        if rem != '0': current_intermediate_number = str(rem) + current_intermediate_number
        intermediate_numbers.append(current_intermediate_number)
    result = intermediate_numbers[0]
    for k in range(1, len(intermediate_numbers)):
        result = sb_addition(result, intermediate_numbers[k])
    if not(arg1_is_full_integer) or not(arg2_is_full_integer):
        result = result[:-len(arg1_decimal_part+arg2_decimal_part)]+'.'+result[len(result)-len(arg1_decimal_part+arg2_decimal_part):] #here to modifiy
    if (arg1_is_negative and not(arg2_is_negative)) or (not(arg1_is_negative) and arg2_is_negative): result = '-' + result
    result = good_format(result)
    return result

def good_format(result: str) -> str:
    # order of following instructions is very important
    while result.startswith('0') and len(result)>=2 and result[1] != '.': result = result[1:]
    while result.startswith('-0') and len(result)>=3 and result[2] != '.': result = result.replace('-0','-')
    if '.' in result and result.split('.')[1]=='0'*len(result.split('.')[1]): result = result.split('.')[0]
    while '.' in result and result.endswith('0'): result = result[:-1]
    return result


if __name__=='__main__':
    #print("add", sb_addition("2222222222222222222222222222222222222222.55", "2.55") )
    #print("add", sb_addition("3.8257", "0.8257") )
    #print( type(sb_substract("9999999.019999", "99999.99999993")) )
    #print("sub", sb_substract("12", "78.9999") )
    #print(greater_than("0","1110", "0","1112", True, True))
    #print(greater_than("0","0", "1110","1112"))
    #print(greater_than('9001','9003'))
    print("mul", sb_multiply('123','123.0'))
    #=======================
    #print("sb_addition('14','19977.67')", sb_addition('14','19977.67'))
    #print("sb_substract('559.1','6.98')", sb_substract('559.1','6.98'))
    #print("sb_multiply( sb_addition('14','19977.67') , sb_substract('559.1','-6.98') )",sb_multiply( sb_addition('14','19977.67') , sb_substract('559.1','-6.98') ))
    print("cmplx:", sb_multiply( sb_multiply( sb_addition('14','19977.67') , sb_substract('559.1','6.98') ),'0.1459'))
    print("format", good_format('-00001.000'))
    print("overlap",overlap('-12512.252','125'))
    ov_r = overlap('-12512.252','125')
    print(unoverlap(ov_r))
    pass