package fundamentals.stack.validation.lc020_validparentheses;

import java.util.Stack;

/**
 * Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid.
 * The brackets must close in the correct order, "()" and "()[]{}" are all valid but "(]" and "([)]" are not.
 */
public class Solution {

    public boolean isValid(String str) {
        Stack<Character> s = new Stack<>();
        for (char c : str.toCharArray()) {
            if ("([{".indexOf(c) >= 0) s.push(c);
            else if (s.isEmpty() || (c == ')' && s.pop() != '(') ||
                    (c == ']' && s.pop() != '[') || (c == '}' && s.pop() != '{'))
                return false;
        }
        return s.isEmpty();
    }

    // My 3AC: simplified further!
    public boolean isValid3(String str) {
        Stack<Character> s = new Stack<>();
        for (char c : str.toCharArray()) {
            if (c == '(' || c == '{' || c == '[') {
                s.push(c);
            } else {
                if (s.isEmpty() ||
                        (c == ')' && s.pop() != '(') ||
                        (c == '}' && s.pop() != '{') ||
                        (c == ']' && s.pop() != '['))
                    return false;
            }
        }
        return s.isEmpty();
    }

    // A Simple one!
    public boolean isValid_simple(String s) {
        Stack<Character> stack = new Stack<>();
        for (char c : s.toCharArray()) {
            if (c == '(' || c == '{' || c == '[') {
                stack.push(c);
            } else {
                if (stack.isEmpty()) return false;
                else if (c == ')' && stack.pop() != '(') return false;
                else if (c == '}' && stack.pop() != '{') return false;
                else if (c == ']' && stack.pop() != '[') return false;
                /* else true */
            }
        }
        return stack.isEmpty();
    }

    // My 2AC
    public boolean isValid2(String s) {
        Stack<Character> stack = new Stack<>();
        for (char c : s.toCharArray()) {
            switch (c) {
                case '(':
                case '{':
                case '[':
                    stack.push(c);
                    break;
                case ')':
                    if (stack.isEmpty() || stack.pop() != '(') {
                        return false;
                    }
                    break;
                case ']':
                    if (stack.isEmpty() || stack.pop() != '[') {
                        return false;
                    }
                    break;
                case '}':
                    if (stack.isEmpty() || stack.pop() != '{') { // error2: stack could be empty
                        return false;
                    }
                    break;
                default:
                    return false;
            }
        }
        return stack.isEmpty(); // error1: don't return true directly!
    }

    // My 1AC
    public boolean isValid1(String s) {
        Stack<Character> stack = new Stack<>();
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            switch (c) {
                case '(':
                case '{':
                case '[':
                    stack.push(c);
                    break;
                case ')':
                    if (stack.isEmpty() || stack.pop() != '(') {
                        return false;
                    }
                    break;
                case '}':
                    if (stack.isEmpty() || stack.pop() != '{') {
                        return false;
                    }
                    break;
                case ']':
                    if (stack.isEmpty() || stack.pop() != '[') {
                        return false;
                    }
                    break;
                default:
                    return false;
            }
        }
        return stack.isEmpty();
    }

}

@@ -448,37 +448,79 @@
 or (
+int i = 0; i %3C str.length(); i++) %7B%0A            
 char c 
-:
+=
  str.
-toC
+c
 harA
-rray()) %7B
+t(i);
 %0A   
@@ -536,29 +536,40 @@
 if (
-%22(%5B%7B%22.indexOf(c) %3E= 0
+c == '(' %7C%7C c == '%5B' %7C%7C c == '%7B'
 ) s.
@@ -608,24 +608,44 @@
 isEmpty() %7C%7C
+%0A                   
  (c == ')' &
@@ -716,16 +716,36 @@
  '%5B') %7C%7C
+%0A                   
  (c == '
@@ -766,32 +766,16 @@
 != '%7B'))
-%0A               
  return 

valid parentheses