Balanced Parentheses Validator with Nesting Depth

Code GenerationDifficulty: MEDIUM11 models comparedTotal cost: $0.015714

Prompt

Write a Python function called `analyze_brackets` that takes a string and returns a dictionary with the following keys:

- `valid`: bool — True if all brackets are properly balanced and nested
- `max_depth`: int — the maximum nesting depth reached (0 if no brackets or invalid)
- `unmatched_open`: int — count of unmatched opening brackets at end of string
- `unmatched_close`: int — count of unmatched closing brackets encountered before any match

The function must handle THREE types of brackets: `()`, `[]`, `{}`.

Brackets of different types must be properly matched (e.g., `([)]` is invalid even though counts are equal).

Edge cases to handle:
- Empty string → `{'valid': True, 'max_depth': 0, 'unmatched_open': 0, 'unmatched_close': 0}`
- String with no brackets → same as empty string
- Mismatched types count the open bracket as unmatched_open and the close bracket as unmatched_close
- If the string is invalid, `max_depth` should still reflect the deepest valid nesting reached before failure... actually, `max_depth` should be the overall maximum stack depth reached during processing (even for invalid strings)

Example behavior:
- `analyze_brackets('({[]})')` → `{'valid': True, 'max_depth': 3, 'unmatched_open': 0, 'unmatched_close': 0}`
- `analyze_brackets('([)]')` → `{'valid': False, 'max_depth': 2, 'unmatched_open': 1, 'unmatched_close': 1}`
- `analyze_brackets('(((...)))')` with 3 open and 4 close → `{'valid': False, 'max_depth': 3, 'unmatched_open': 0, 'unmatched_close': 1}`
- `analyze_brackets('hello (world)')` → `{'valid': True, 'max_depth': 1, 'unmatched_open': 0, 'unmatched_close': 0}`

Do not use any external libraries. Include the function definition only (no test code).

Expected Output

def analyze_brackets(s: str) -> dict:
    matching = {')': '(', ']': '[', '}': '{'}
    opening = set('([{')
    closing = set(')]}')
    
    stack = []
    max_depth = 0
    unmatched_open = 0
    unmatched_close = 0
    valid = True
    
    for ch in s:
        if ch in opening:
            stack.append(ch)
            if len(stack) > max_depth:
                max_depth = len(stack)
        elif ch in closing:
            expected = matching[ch]
            if stack and stack[-1] == expected:
                stack.pop()
            else:
                # Mismatched or no open bracket
                unmatched_close += 1
                valid = False
                if stack and stack[-1] in opening:
                    # The top of stack is an unmatched open of wrong type
                    unmatched_open += 1
                    stack.pop()
    
    unmatched_open += len(stack)
    if len(stack) > 0:
        valid = False
    
    return {
        'valid': valid,
        'max_depth': max_depth,
        'unmatched_open': unmatched_open,
        'unmatched_close': unmatched_close
    }

Model Responses

Claude Opus 4.6

Unrated
4,505ms790 tokens
```python def analyze_brackets(s): matching = {')': '(', ']': '[', '}': '{'} openers = set('([{') closers = set(')]}') stack = [] max_depth = 0 unmatched_close = 0 for char in s: if char in openers: stack.append(char) if len(stack) > max_depth: max_depth = len(stack) elif char in closers: if stack and stack[-1] == matching[char]: stack.pop() else: unmatched_close += 1 unmatched_open = len(stack) valid = (unmatched_open == 0 and unmatched_close == 0) return { 'valid': valid, 'max_depth': max_depth, 'unmatched_open': unmatched_open, 'unmatched_close': unmatched_close } ```

GPT-4.1

Unrated
3,225ms754 tokens
```python def analyze_brackets(s): open_to_close = {'(': ')', '[': ']', '{': '}'} close_to_open = {')': '(', ']': '[', '}': '{'} stack = [] max_depth = 0 unmatched_open = 0 unmatched_close = 0 for char in s: if char in open_to_close: stack.append(char) if len(stack) > max_depth: max_depth = len(stack) elif char in close_to_open: if not stack: unmatched_close += 1 else: if stack[-1] == close_to_open[char]: stack.pop() else: # mismatched type: count both an unmatched open and close unmatched_open += 1 unmatched_close += 1 stack.pop() # Remove the offending open, if any, and continue unmatched_open += len(stack) valid = (unmatched_open == 0 and unmatched_close == 0) # For empty string or no bracket, max_depth should be 0 if max_depth == 0: unmatched_open = 0 unmatched_close = 0 valid = True return { 'valid': valid, 'max_depth': max_depth, 'unmatched_open': unmatched_open, 'unmatched_close': unmatched_close } ```

GPT-4.1 Mini

Unrated
3,703ms751 tokens
```python def analyze_brackets(s): pairs = {')': '(', ']': '[', '}': '{'} open_brackets = set(pairs.values()) stack = [] max_depth = 0 unmatched_close = 0 unmatched_open = 0 for ch in s: if ch in open_brackets: stack.append(ch) if len(stack) > max_depth: max_depth = len(stack) elif ch in pairs: if not stack: # unmatched closing bracket unmatched_close += 1 else: top = stack.pop() if pairs[ch] != top: # mismatch: top is unmatched_open, current ch unmatched_close unmatched_open += 1 unmatched_close += 1 # remaining unmatched opening brackets unmatched_open += len(stack) valid = (unmatched_open == 0 and unmatched_close == 0) if not s or all(ch not in open_brackets and ch not in pairs for ch in s): # Empty or no brackets return {'valid': True, 'max_depth': 0, 'unmatched_open': 0, 'unmatched_close': 0} return { 'valid': valid, 'max_depth': max_depth, 'unmatched_open': unmatched_open, 'unmatched_close': unmatched_close } ```

GPT-4.1 Nano

Unrated
2,220ms772 tokens
```python def analyze_brackets(s): # Mapping of closing to opening brackets brackets_map = {')': '(', ']': '[', '}': '{'} # Sets for quick checking opening_brackets = set(brackets_map.values()) closing_brackets = set(brackets_map.keys()) stack = [] max_depth = 0 unmatched_open = 0 unmatched_close = 0 is_valid = True for ch in s: if ch in opening_brackets: stack.append(ch) if len(stack) > max_depth: max_depth = len(stack) elif ch in closing_brackets: if not stack: # Unmatched closing bracket unmatched_close += 1 is_valid = False else: top = stack.pop() if brackets_map[ch] != top: # Mismatched pair unmatched_open += 1 unmatched_close += 1 is_valid = False # Ignore other characters # After processing all characters unmatched_open = len(stack) + unmatched_open # If stack is not empty, unmatched_open includes remaining open brackets # The unmatched_open count should include unmatched open brackets still on stack # Validity if stack: is_valid = False return { 'valid': is_valid, 'max_depth': max_depth, 'unmatched_open': unmatched_open, 'unmatched_close': unmatched_close } ```

o3

Unrated
29,742ms3453 tokens
```python def analyze_brackets(text: str) -> dict: """ Analyze a string that may contain three kinds of brackets – (), [] and {} – and return a dictionary with information about balance, nesting depth and unmatched brackets. """ # Mapping: opening → closing pairs = {'(': ')', '[': ']', '{': '}'} # Reverse mapping: closing → opening reverse = {v: k for k, v in pairs.items()} openings = set(pairs) closings = set(reverse) stack = [] # keeps opening brackets max_depth = 0 # deepest stack size reached unmatched_open = 0 # counted as we discover mismatches / leftovers unmatched_close = 0 # counted as we discover mismatches valid = True # will be flipped to False on first error for ch in text: if ch in openings: stack.append(ch) if len(stack) > max_depth: max_depth = len(stack) elif ch in closings: # Nothing to match with if not stack: unmatched_close += 1 valid = False break top = stack[-1] # Correct match if pairs[top] == ch: stack.pop() else: # Type-mismatch — both brackets are unmatched unmatched_open += 1 # the opening on the stack unmatched_close += 1 # the current closing stack.pop() # discard the unmatched opening valid = False break # any other character is ignored # Any still-open brackets left after full scan if valid and stack: valid = False unmatched_open += len(stack) return { 'valid': valid, 'max_depth': max_depth if valid or max_depth else 0, 'unmatched_open': unmatched_open, 'unmatched_close': unmatched_close } ```

o3 Mini

Unrated
24,937ms4114 tokens
def analyze_brackets(s: str) -> dict: # Define mapping of opening to closing brackets. bracket_map = {'(': ')', '[': ']', '{': '}'} # Create a set for quick membership tests. open_brackets = set(bracket_map.keys()) close_brackets = {v: k for k, v in bracket_map.items()} stack = [] # will store opening brackets max_depth = 0 unmatched_close = 0 # count of closing brackets with no proper match # We also track if at least one mismatch occurred (when a closing bracket doesn't match the current top). mismatch_found = False # Iterate through each character in the string. for char in s: if char in open_brackets: stack.append(char) # Update maximum depth reached. if len(stack) > max_depth: max_depth = len(stack) elif char in close_brackets: # If there is no open bracket to match, count as unmatched close. if not stack: unmatched_close += 1 else: # Check if the most recent open bracket matches the closing bracket. if bracket_map[stack[-1]] == char: stack.pop() else: # Mismatched type: count the current closing bracket as unmatched. unmatched_close += 1 # Mark a mismatch. mismatch_found = True # Do not pop the stack to allow future characters a chance to match; # this seems to match the expected behavior for cases like "([)]". # Count any remaining open brackets as unmatched. unmatched_open = len(stack) # Determine overall validity: # The string is valid only if no mismatches happened, no unmatched closing brackets were found, # and no unmatched opening brackets remain. valid = (unmatched_close == 0 and unmatched_open == 0 and not mismatch_found) return { 'valid': valid, 'max_depth': max_depth, 'unmatched_open': unmatched_open, 'unmatched_close': unmatched_close }

o4 Mini

Unrated
32,413ms4139 tokens
```python def analyze_brackets(s): opening = {'(', '[', '{'} matching = {')': '(', ']': '[', '}': '{'} stack = [] unmatched_open = 0 unmatched_close = 0 max_depth = 0 valid = True for ch in s: if ch in opening: stack.append(ch) if len(stack) > max_depth: max_depth = len(stack) elif ch in matching: if not stack: # Extra closing bracket with no matching open unmatched_close = 1 valid = False break if stack[-1] == matching[ch]: stack.pop() else: # Mismatched types unmatched_open = 1 # the open bracket on top of stack unmatched_close = 1 # this closing bracket valid = False break # ignore other characters if valid: # any opens left are unmatched unmatched_open = len(stack) unmatched_close = 0 valid = (unmatched_open == 0) return { 'valid': valid, 'max_depth': max_depth, 'unmatched_open': unmatched_open, 'unmatched_close': unmatched_close } ```

GPT-4o Mini

Unrated
7,330ms667 tokens$0.000195
```python def analyze_brackets(s: str) -> dict: stack = [] max_depth = 0 unmatched_close = 0 matching_brackets = {')': '(', ']': '[', '}': '{'} for char in s: if char in '([{': stack.append(char) max_depth = max(max_depth, len(stack)) elif char in ')]}': if stack and stack[-1] == matching_brackets[char]: stack.pop() # Match found, pop the opening bracket else: unmatched_close += 1 # Unmatched closing bracket # Count this closing bracket as unmatched and won't pop anything from the stack unmatched_open = len(stack) # Remaining unmatched opening brackets return { 'valid': unmatched_open == 0 and unmatched_close == 0, 'max_depth': max_depth, 'unmatched_open': unmatched_open, 'unmatched_close': unmatched_close } ```

Claude Haiku 4.5

Unrated
2,319ms915 tokens$0.002471
```python def analyze_brackets(s): """ Analyze bracket balance, nesting depth, and unmatched brackets in a string. Args: s: A string that may contain brackets: (), [], {} Returns: A dictionary with keys: valid, max_depth, unmatched_open, unmatched_close """ opening = {'(', '[', '{'} closing = {')', ']', '}'} pairs = {'(': ')', '[': ']', '{': '}'} reverse_pairs = {')': '(', ']': '[', '}': '{'} stack = [] max_depth = 0 unmatched_close = 0 valid = True for char in s: if char in opening: stack.append(char) max_depth = max(max_depth, len(stack)) elif char in closing: if stack and reverse_pairs[char] == stack[-1]: # Matching closing bracket stack.pop() else: # Unmatched closing bracket unmatched_close += 1 valid = False # Remaining opening brackets are unmatched unmatched_open = len(stack) if unmatched_open > 0: valid = False return { 'valid': valid, 'max_depth': max_depth, 'unmatched_open': unmatched_open, 'unmatched_close': unmatched_close } ```

GPT-4o

Unrated
3,320ms748 tokens$0.004060
```python def analyze_brackets(s): # Initializing the response dictionary result = { 'valid': True, 'max_depth': 0, 'unmatched_open': 0, 'unmatched_close': 0 } stack = [] max_depth = 0 unmatched_close = 0 # Define pairs of brackets open_to_close = {'(': ')', '[': ']', '{': '}'} close_to_open = {')': '(', ']': '[', '}': '{'} for char in s: if char in open_to_close: stack.append(char) # Update the max_depth based on stack length max_depth = max(max_depth, len(stack)) elif char in close_to_open: if stack and stack[-1] == close_to_open[char]: stack.pop() else: unmatched_close += 1 result['valid'] = False # any remaining in stack are unmatched open brackets unmatched_open = len(stack) # Update result dictionary result['valid'] = result['valid'] and (unmatched_open == 0 and unmatched_close == 0) result['max_depth'] = max_depth result['unmatched_open'] = unmatched_open result['unmatched_close'] = unmatched_close return result ```

Claude Sonnet 4.6

Unrated
7,433ms1020 tokens$0.008988
```python def analyze_brackets(s: str) -> dict: """ Analyze bracket usage in a string. Returns a dictionary with: - valid: bool — True if all brackets are properly balanced and nested - max_depth: int — maximum nesting depth reached during processing - unmatched_open: int — count of unmatched opening brackets - unmatched_close: int — count of unmatched closing brackets """ opening = set('([{') closing = set(')]}') matches = {')': '(', ']': '[', '}': '{'} stack = [] max_depth = 0 unmatched_open = 0 unmatched_close = 0 valid = True for char in s: if char in opening: stack.append(char) current_depth = len(stack) if current_depth > max_depth: max_depth = current_depth elif char in closing: expected_open = matches[char] if not stack: # No opening bracket to match against unmatched_close += 1 valid = False elif stack[-1] == expected_open: # Proper match — pop the stack stack.pop() else: # Mismatched bracket types # The top of stack is an unmatched open, this close is unmatched unmatched_open += 1 unmatched_close += 1 valid = False stack.pop() # Any remaining items on the stack are unmatched open brackets unmatched_open += len(stack) if len(stack) > 0: valid = False return { 'valid': valid, 'max_depth': max_depth, 'unmatched_open': unmatched_open, 'unmatched_close': unmatched_close, } ```

Cost & Performance Comparison

ModelLatencyTokensCostVerdict
Claude Opus 4.64,505ms790
GPT-4.13,225ms754
GPT-4.1 Mini3,703ms751
GPT-4.1 Nano2,220ms772
o329,742ms3,453
o3 Mini24,937ms4,114
o4 Mini32,413ms4,139
GPT-4o Mini7,330ms667$0.000195
Claude Haiku 4.52,319ms915$0.002471
GPT-4o3,320ms748$0.004060
Claude Sonnet 4.67,433ms1,020$0.008988