Search code examples
pythonstringeval

Python: apply math order of operations to reorder strings following hierarchy in parentheses


How can be done with Python to reorder a string applying the math operations order with parenthesys?

Let me use an example:

"son(father(granpa)mother))" ===> "granpa father mother son"

The idea is to reorder the original string using the standar math order operations. In the math order operations, parenthesys has the highest priority. Let me use a math example:

4 + (5 + (3 + 3)) = ((3 + 3) + 5 ) + 4 = 3 + 3 + 5 + 4 = 14

EDIT: This example uses just + because python always do * before +, in the same parenthesys level, thats not the point, the point is the order in strings because will only concatenate the result reordering it.

The target is to reorder a string containing variables to study posible optimizations to operations. Example of string I want to reorder:

def xor_with_nands(a,b):
  return f"~(~(~({a} & {b}) & {a}) & ~(~({a} & {b}) & {b}))"

>> xor_with_nands(0,1)
>> ~(~(~(0 & 1) & 0) & ~(~(0 & 1) & 1))
>> eval(xor_with_nands(0,1))
>> 1

If there is a way to create a function that reorders the strings respecting the mathematical order of the parentheses (just parenthses, not other math operations order), it may be possible to analyze optimizations in some processes.

The goal is to get a tool that visualizes nested logical operations in order of execution to visually understand them and hopefully simplify them.

Conclusion: Shunting Yard Algorithm is amazing. Thank you very much!


Solution

  • You are looking for a Shunting Yard Algorithm.

    This will convert your math notation (also known as infix notation) into a format that can easily be processed by a computer (known as postfix notation). See here: https://en.wikipedia.org/wiki/Shunting-yard_algorithm for a better description.

    Essentially, this algorithm will take your expression as convert it into queue which is already ordered correctly.

    Here is some pseudocode taken from Brilliant.org:

    1.  While there are tokens to be read:
    2.        Read a token
    3.        If it's a number add it to queue
    4.        If it's an operator
    5.               While there's an operator on the top of the stack with greater precedence:
    6.                       Pop operators from the stack onto the output queue
    7.               Push the current operator onto the stack
    8.        If it's a left bracket push it onto the stack
    9.        If it's a right bracket 
    10.            While there's not a left bracket at the top of the stack:
    11.                     Pop operators from the stack onto the output queue.
    12.             Pop the left bracket from the stack and discard it
    13. While there are operators on the stack, pop them to the queue
    

    This will allow you to define your custom operators and define their precedence.