Codesignal - 152 - First Operation Character

Codesignal - 152 - First Operation Character

·

3 min read

Attempting to catch up on a backlog of study days. My focus has been on a coding question a day (sometimes it span multiple days) or a system design problem/chapter/video a day. So far it's been 215 days with approximately 30 day total gaps. Currently just making my way to complete all the problems in CodeSignal before moving back to LeetCode and CodeWars

Today's problem:

Given a string which represents a valid arithmetic expression, find the index of the character in the given expression corresponding to the arithmetic operation which needs to be computed first.

Note that several operations of the same type with equal priority are computed from left to right.

See the explanation of the third example for more details about the operations priority in this problem.

Example

For expr = "(2 + 2) * 2", the output should be solution(expr) = 3.

There are two operations in the expression: + and *. The result of + should be computed first, since it is enclosed in parentheses. Thus, the output is the index of the '+' sign, which is 3.

For expr = "2 + 2 * 2", the output should be solution(expr) = 6.

There are two operations in the given expression: + and . Since there are no parentheses, should be computed first as it has higher priority. The answer is the position of '*', which is 6.

For expr = "((2 + 2) 2) 3 + (2 + (2 * 2))", the output should be solution(expr) = 28.

There are two operations which are enclosed in two parentheses: + at the position 4, and at the position 28. Since has higher priority than +, the answer is 28

The dislikes outweighed the likes 2 to 1. Great, I thought, but it ended up being quick to solve compared to other problems.

The logic to process enclosed parentheses is similar to the Valid Parentheses problem.

Initially I considered parsing the string into an n-ary tree based off levels of parentheses with the operator as the value, but seemed overkill.

# Time Complexity: O(n) + m*log(m) where n is the expression and m number of operators.
# Space Complexity: O(m)
def solution(expr):
    eval_tree, i, level, operators = [], 0, 0, {'+': 0, '-': 0, '/': 1, '//': 1, '*': 1}
    while i < len(expr):
        if expr[i]  == '(':
            level += 1
        elif expr[i] in operators:
            eval_tree.append( (level, operators[expr[i]], i) )
        elif expr[i] == ')':
            level -= 1
        i += 1
    sorted_eval_tree = sorted(eval_tree, key=lambda element: (element[0], element[1]), reverse=True)
    return sorted_eval_tree[0][2]

The top rated solution has a time complexity of O(n) + m O(n) where m is a constant 2 ( and +) and a space complexity of O(1). Another interesting approach was to use regular expressions.