Esempio n. 1
0
 public override int Execute(CalculatorNumber left, CalculatorNumber right) => left.Value - right.Value;
Esempio n. 2
0
 public abstract int Execute(CalculatorNumber left, CalculatorNumber right);
        /// <summary>
        /// Reorder the operations in the opertionsOrder Queue by weight of operation
        /// </summary>
        /// <param name="operationOrder">Queue of operations</param>
        /// <returns>CalculatorCalculation ready for calculations to be executed</returns>
        private CalculatorCalculation OrderCalculations(Queue <object> operationOrder)
        {
            //The originCalculator is the top of the binary tree structure for the operations order
            var originCalculator = new CalculatorCalculation();
            //The current calculation, start with the origin
            var currentCalculator = originCalculator;

            //The stack for determining the current parentheses we are in
            var parenthesesStack = new Stack <CalculatorCalculation>();

            //Loop through all the opearations and order them according to the order of operations
            foreach (object operation in operationOrder)
            {
                //Put the number associated with the operation to the right of the tree as a single number
                if (operation is OperationCalc operationCalc)
                {
                    var rightCalculator = new CalculatorNumber(operationCalc.X);
                    currentCalculator.Right = rightCalculator;

                    if (operation is OperationPair operationPair)
                    {
                        currentCalculator.PairCalc = operationPair.CalcPair;
                        currentCalculator.Weight   = operationPair.Weight;
                    }
                    else if (operation is OperationNum)
                    {
                        //If the Operation is an OperationNum, don't assign a calculation
                        //and make the weight -1 so its operation order is never checked
                        currentCalculator.Weight = -1;
                    }
                }
                //Operation is an OperationParentheses
                else
                {
                    var operationParentheses = (OperationParentheses)operation;

                    //Check if operation is a right parentheses
                    if (operationParentheses.Parentheses == Parentheses.RIGHT)
                    {
                        //Set the parentheses calculation with a weight -1 so its operation order is never checked
                        currentCalculator.Weight = -1;
                        currentCalculator.Right  = new CalculatorCalculation()
                        {
                            Top = currentCalculator
                        };
                        parenthesesStack.Push(currentCalculator);

                        currentCalculator = (CalculatorCalculation)currentCalculator.Right;

                        continue;
                    }
                    //The operation is a left parentheses
                    else
                    {
                        var rightParentheses = parenthesesStack.Pop();

                        if (operationParentheses.calcPair != null)
                        {
                            rightParentheses.Weight   = operationParentheses.Weight;
                            rightParentheses.PairCalc = operationParentheses.calcPair;
                            currentCalculator         = rightParentheses;
                        }
                        else
                        {
                            var tempTop = (CalculatorCalculation)rightParentheses.Top;
                            //If extraneous parentheses surround the given string operation the top calculation
                            //will end up as a parentheses, and subsequently have no left operation
                            //Check if there is a calculation above the current parentheses, otherwise don't add to left.
                            if (tempTop != null)
                            {
                                tempTop.Left = rightParentheses;
                            }

                            continue;
                        }
                    }
                }

                //The CalculatorCalculation above the current CalculationCalculator in the binary tree
                var topCalculator = (CalculatorCalculation)currentCalculator.Top;

                //Check if we are on the originCalculator
                if (topCalculator != null)
                {
                    //Don't change operations order if the currentCalculator is a OperationNum
                    if (topCalculator.Weight != -1 && currentCalculator.Weight != -1)
                    {
                        //If the currentCalculators weight is less than it's top weight, sink the top to its right
                        if (currentCalculator.Weight < topCalculator.Weight)
                        {
                            var tempCurrentCalculator = currentCalculator;
                            var tempTopCalculator     = topCalculator;

                            //Loop until the weights have been reordered
                            while (tempCurrentCalculator.Weight < tempTopCalculator.Weight)
                            {
                                //Create a newTopCalculator to replace the current Top calculator
                                //The current Top calculator will sink to the new Top calculators right
                                //and the new Top calculators operation will become the operation of the current calculator
                                var newTopCalculator = new CalculatorCalculation()
                                {
                                    PairCalc = tempCurrentCalculator.PairCalc,
                                    Right    = tempTopCalculator,
                                    Top      = tempTopCalculator.Top
                                };

                                tempTopCalculator.Left = tempCurrentCalculator.Right;
                                tempTopCalculator.Top  = newTopCalculator;
                                //If the current Top calculator was the origin, make the new Top calculator the new origin
                                if (originCalculator == tempTopCalculator)
                                {
                                    originCalculator = newTopCalculator;
                                }

                                //Make the current calculator the newTopCalculator to check if the new Top calculator
                                //has a weight less than the new Top calculators Top.
                                tempCurrentCalculator = newTopCalculator;
                                tempTopCalculator     = (CalculatorCalculation)tempCurrentCalculator.Top;

                                if (tempTopCalculator != null)
                                {
                                    if (tempTopCalculator.Weight != -1)
                                    {
                                        tempTopCalculator.Left = newTopCalculator;
                                    }
                                    else
                                    {
                                        tempTopCalculator.Right = newTopCalculator;
                                    }
                                }
                                //If there is no Top calculator break the loop
                                else
                                {
                                    break;
                                }
                            }

                            currentCalculator = tempCurrentCalculator;
                        }
                        else
                        {
                            //If the weights were already ordered, add the currentCalculator to the left of the Top
                            //Don't add to the left if the topCalculator has the weight of a parentheses
                            if (topCalculator.Weight != -1)
                            {
                                topCalculator.Left = currentCalculator;
                            }
                        }
                    }
                    else
                    {
                        //If the current calculator is a OperationNum, add the currentCalculator to the left of the Top
                        //Don't add to the left if the topCalculator has the weight of a parentheses
                        if (topCalculator.Weight != -1)
                        {
                            topCalculator.Left = currentCalculator;
                        }
                    }
                }

                //Setup the currentCalculator as the new Top for the next CalculationCalculator in the loop
                currentCalculator = new CalculatorCalculation()
                {
                    Top = currentCalculator
                };
            }

            return(originCalculator);
        }