//Returns true if all parens are matched and properly closed
        //Uses an ArrayStack to match parens
        private static bool ParensMatch(string input)
        {
            ArrayStack <char> parensStack = new ArrayStack <char>();

            foreach (char c in input)
            {
                if (c.CompareTo('(') == 0)
                {
                    parensStack.Push(c);
                }
                else if (c.CompareTo(')') == 0)
                {
                    if (parensStack.IsEmpty() || parensStack.Pop().CompareTo('(') != 0)
                    {
                        return(false);
                    }
                }
            }
            if (!parensStack.IsEmpty())
            {
                return(false);
            }
            return(true);
        }
        //Given a string denoting an infix math expression, converts to postfix
        //Uses Dijkstra's Shunting-Yard Algorithm
        private static string ConvertInfixToPostfix(string input)
        {
            string[]      values = input.Split(' ');
            StringBuilder rpn    = new StringBuilder(input.Length);
            ArrayDictionary <string, int> operators = new ArrayDictionary <string, int>(5);

            operators.Add("^", 4);
            operators.Add("*", 3);
            operators.Add("x", 3);
            operators.Add("/", 3);
            operators.Add("+", 2);
            operators.Add("-", 2);
            operators.Add("(", -1);
            operators.Add(")", -1);
            ArrayStack <string> operatorStack = new ArrayStack <string>();

            foreach (string item in values)
            {
                if (item.Equals(""))
                {
                    break;
                }
                if (operators.ContainsKey(item)) //item is an operator
                {
                    if (operatorStack.Size == 0) //stack is empty, we push operator to stack
                    {
                        operatorStack.Push(item);
                        continue;
                    }

                    if (item.Equals(")")) //we have a right paren
                    {
                        bool found = false;
                        while (!operatorStack.IsEmpty()) //searching for left paren
                        {
                            if (operatorStack.Peek().Equals("("))
                            {
                                found = true;
                                operatorStack.Pop();
                                break;
                            }
                            else
                            {
                                rpn.Append(operatorStack.Pop());
                                rpn.Append(" ");
                            }
                        }
                        if (!found && operatorStack.IsEmpty()) //stack empty, no left paren in sight
                        {
                            throw new ArgumentException("Mismatched parens");
                        }
                    }
                    else if (item.Equals("(")) //left parens always added to stack
                    {
                        operatorStack.Push(item);
                    }
                    else //we have an operator
                    {
                        if (item.Equals("^") && operators[item] < operators[operatorStack.Peek()])
                        {
                            rpn.Append(operatorStack.Pop());
                            rpn.Append(" ");
                        }
                        else if (operators[item] <= operators[operatorStack.Peek()])
                        {
                            rpn.Append(operatorStack.Pop());
                            rpn.Append(" ");
                        }
                        operatorStack.Push(item);
                    }
                }
                else //item is a number
                {
                    double n;
                    if (!double.TryParse(item, out n))
                    {
                        throw new FormatException("Invalid input of number");
                    }
                    rpn.Append(n);
                    rpn.Append(" ");
                }
            }
            while (!operatorStack.IsEmpty()) //we're done, dump stack onto output
            {
                if (operatorStack.Peek().Equals(")") || operatorStack.Peek().Equals("("))
                {
                    throw new ArgumentException("Mismatched parens");
                }
                rpn.Append(operatorStack.Pop());
                rpn.Append(" ");
            }

            return(rpn.ToString().Trim());
        }