# embedding.py
# Lillian Lee (LJL2@cornell.edu)
# Mar 5, 2014

""" Demonstrate recursive computation of the embeddedness of a list"""


def embed(input):
    """Returns: level of embedding of <input>.

    Precondition: input is a string, or a non-empty potentially nested list of strings
    representing a valid sentence bracketing; no component list can be empty."""

    return 0 if type(input) != list else (1 + max(map(embed,input)))


def embed_if(input):
    """Returns: level of embedding of <input>.

    Precondition: input is a string, or a non-empty potentially nested list of strings
    representing a valid sentence bracketing; no component list can be empty."""
    # less condensed code
    if type(input) != list:
        return 0
    else: # input is a (non-empty) list
        return 1 + max(map(embed_if,input))


def embed_alt_if(input):
    """Returns: level of embedding of <input>.

    Precondition: input is a string, or a non-empty potentially nested list of strings
    representing a valid sentence bracketing; no component list can be empty."""
    # Less condensed code, using "if" without "else" since a return statement
    # ends execution.
    if type(input) != list:
        return 0

    # input is a (non-empty) list
    return 1 + max(map(embed_alt_if,input))


# Note extra precondition! Can you figure out why it's needed?
# How would you prove that this code is correct?
def embed_nonrecursive(input):
    """Returns: level of embedding of <input>.

    Precondition: input is a string, or a non-empty potentially nested list of strings
    representing a valid sentence bracketing; no component list can be empty.

    Furthermore, no component string can contain any square brackets."""
    # convert the list to a bracketed string.
    input_string = str(input)

    max_so_far = 0 # maximum number of "open" '['s found so far.
    num_curr_open = 0 # number of currently unmatched '['s

    for c in input_string:
        if c == '[':
            num_curr_open = num_curr_open + 1
        elif c == ']':
            num_curr_open = num_curr_open - 1
        max_so_far = max(max_so_far,num_curr_open)

    return max_so_far


def embed_reverse_conditional(input):
    """Returns: level of embedding of <input>.

    Precondition: input is a string, or a non-empty potentially nested list of strings
    representing a valid sentence bracketing; no component list can be empty."""
    # This is the more conventional order ("expected case first" for conditional
    # expressions), but it puts the base case last.  Note that the order of
    # evaluation is to actually start with the middle part (the part after the
    # "if")
    return (1 + max(map(embed_reverse_conditional,input))) if type(input) == list else 0