public override int Execute(CalculatorNumber left, CalculatorNumber right) => left.Value - right.Value;
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); }