1

I got this problem in a coding challenge. I couldn't solve it on time but I still want to know how could it be done. I am not very familiar with expression trees and I found it hard to model the problem. The description goes like this:

Input: expression_tree | sequence_of_operations

The input is a single line of text with a expression tree and a sequence of operations separated by | character and ended by a \n newline character. Spaces are allowed in the input but should be ignored.

The expression tree is a sequence of 1-character variables A-Z and with sub expression trees formed by parenthesis (expression_tree). Examples: AB, A(B C D), (AB)C((DE)F)

The sequence of operations is a string of with characters R (reverse) or S (simplify)

Reverse means reverse the order of everything in expression tree. Applying reverse twice in a row cancels out. Example: (AB)C((DE)F) | R should print (F(ED))C(BA)

Simplify means remove the parentheses around the very first element in the expression tree and each of its subexpression trees. Applying S multiple times should have same result as applying S once. Example: (AB)C((DE)F) | S should print ABC(DEF)

Output: Read the expression tree and apply the sequence of operations from left to right to the expression tree, print out the result without characters.

What I would like to know the most is how to model the expression tree to handle the parentheses and how does the simplify operation should work?

1

1 Answer 1

1
'''
Examples are as follows :
INPUT:
(AB)(C(DE))/SS
(((AB)C)D)E/SS
(((AB)C)D)E/SR
(AB)C((DE)F)/SRS
(AB(CD((EF)G)H))(IJ)/SRS
(AB(CD((EF)G)H))(IJ)/SSSRRRS
(A(B(C)D)E(FGH(IJ)))/SRRSSRSSRRRSSRS
(A(BC(D(E((Z)K(L)))F))GH(IJK))/S
-------------------------------
OUTPUT:
AB(C(DE))
ABCDE
EDCBA
FEDCBA
JI(H(GFE)DC)BA
JI(H(GFE)DC)BA
JIHFGE(D(C)B)A
A(BC(D(E(ZK(L)))F))GH(IJK)/S
'''



'''
operationReverse function returns a reversed expression tree 
Example :  AB(CD) -> (DC)BA
'''
def operationReverse(expression):
    '''============== Reversing the whole expressions ================'''
    expression = expression[::-1] 
    expression = list(expression)

    '''========= Replace Closing brace with Opening brace and vice versa ========='''
    for x in range(0, len(expression)):
        if(expression[x] != ')' and expression[x] != '('):
            continue
        elif(expression[x] == ")"):
            expression[x] = "("
        else:
            expression[x] = ")"

    expression = ''.join(expression)
    return expression


'''
operationSimplify function returns a simplified expression tree 
Example :  (AB)(C(DE)) -> AB(C(DE))
operationSimplify uses recursion
'''
def operationSimplify(expression):

    '''========= If no parenthesis found then return the expression as it is because it is already simplified ========='''
    '''========= This is also the base condition to stop recursion ============='''
    if(expression.find('(')==-1):
        return expression


    '''If 1st character is opening brace then find its correspoinding closing brace and remove them and call the function by passing the values between the opening and                 closing brace'''

    if(expression[0] == '('):
        x = 1
        #numOfOpeningBrackets = maintains the count of opening brackets for finding it's corresponding closing bracket
        numOfOpeningBrackets = 1
        while(x < len(expression)):
            if(expression[x] != ')' and expression[x] != '('):
                x = x + 1
                continue
            elif(expression[x] == "("):
                numOfOpeningBrackets = numOfOpeningBrackets + 1
                x = x + 1
            else:
                numOfOpeningBrackets = numOfOpeningBrackets - 1   
                if(numOfOpeningBrackets == 0):
                    posOfCloseBracket = x
                    break         
                x = x + 1 
        expression = operationSimplify(expression[1:posOfCloseBracket]) + expression[posOfCloseBracket+1:]

    '''========= If no parenthesis found then return the expression as it is because it is already simplified ========='''
    if(expression.find('(')==-1):
        return expression

    '''========= Find the opening brace and it's closing brace and new expression tree will be concatenation of start of string till opening brace including the brace and string       with in the opening brace and closing brace passed as an argument to the function itself and the remaining string ========='''
    x = 0
    #numOfOpeningBrackets = maintains the count of opening brackets for finding it's corresponding closing bracket
    recursion = False
    numOfOpeningBrackets = 0
    while (x < len(expression)):
        if(expression[x] != ')' and expression[x] != '('):
                x = x + 1
        elif(expression[x] == "("):
            if(numOfOpeningBrackets == 0 or recursion == True):
                numOfOpeningBrackets = 0
                recursion = False
                posOfStartBracket = x
                y = x
            numOfOpeningBrackets = numOfOpeningBrackets + 1
            x = x + 1
        else:
            numOfOpeningBrackets = numOfOpeningBrackets - 1 
            if(numOfOpeningBrackets == 0):
                posOfCloseBracket = x 
                x = y 
                expression=expression[0:posOfStartBracket+1]+operationSimplify(expression[posOfStartBracket+1:posOfCloseBracket])+expression[posOfCloseBracket:]
                recursion = True
            x = x + 1
    return expression


'''
solution fucntion prints the final result  
'''
def solution(inputString):
    '''========= Remove the spaces from the input ==============='''
    #inputString = inputString.replace("\n","")
    inputString = inputString.replace(" ","")
    inputString = inputString.replace("\t","")
    #inputString = inputString.replace("()","")

    '''=============== The substring before '/' is expression tree and substring after '/' is sequence of operations  ======================'''

    #posOfSlash = Position Of Slash Character
    posOfSlash = inputString.find('/')
    if(posOfSlash == -1):
        print (inputString)
        return
    #expressionTree = Expression Tree
    expressionTree = inputString[0:posOfSlash]
    #seqOfOp = sequence of operations to be performed
    seqOfOp = inputString[posOfSlash+1:]

    '''============ If sequence Of Operations is empty then print the expression tree as it is ============== '''
    if(len(seqOfOp)==0):
        print(expressionTree)
        return


    '''============= Removing all the pairs of RR from the sequence Of Operations =================='''   
    seqOfOp = seqOfOp.replace(r+r,'')

    '''============ All mulptiple S are replaced by one single S ================'''   
    while(seqOfOp.find(s+s) != -1):
        seqOfOp = seqOfOp.replace(s+s,s)

    '''============ If to perform operation R then call operationReverse() else if to perform operation S call operationSimplify() ================'''
    for x in range (0 , len(seqOfOp)):
        if(seqOfOp[x] == r):
            expressionTree = operationReverse(expressionTree)
        else :
            expressionTree = operationSimplify(expressionTree)
    print(expressionTree)
    return



'''======= Global variables r and s representing operations R and S'''
r = 'R'
s = 'S' 
while True:
    try:
        inputString = input()
        '''==================== Calling function solution  ======================'''
        solution(inputString)
    except EOFError:
        break
Sign up to request clarification or add additional context in comments.

1 Comment

Ohh... Actually I do not remember now... I solved it a year ago

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.