namespace Lunar.Evil_Calculator { internal static class ReversePolishNotationSolver { private static List ToReversePolishNotation(List equation) { List reversedEquation = new List(); Stack operators = new Stack(); foreach (Token token in equation) { if (token.tokenType == Token.TokenType.Operand) { reversedEquation.Add(token); } if (token.tokenType == Token.TokenType.Operator) { if (token.value == "(") { operators.Push(token); } else if (token.value == ")") { while (operators.Peek().value != "(") { reversedEquation.Add(operators.Pop()); } operators.Pop(); } else { while (operators.Count != 0 && operators.Peek().priority >= token.priority) { reversedEquation.Add(operators.Pop()); } operators.Push(token); } } } while (operators.Count != 0) { reversedEquation.Add(operators.Pop()); } return reversedEquation; } public static string Solve(List originalEquation) { List reversedEquation = ToReversePolishNotation(originalEquation); Stack stack = new Stack(); foreach (Token token in reversedEquation) { double result, left, right; if (token.tokenType == Token.TokenType.Operand) { stack.Push(token); } if (token.tokenType == Token.TokenType.Operator) { switch (token.value) { case "+": right = Convert.ToDouble(stack.Pop().value); left = Convert.ToDouble(stack.Pop().value); result = left + right; stack.Push(new Token(Token.TokenType.Operand, result.ToString())); break; case "-": right = Convert.ToDouble(stack.Pop().value); left = Convert.ToDouble(stack.Pop().value); result = left - right; stack.Push(new Token(Token.TokenType.Operand, result.ToString())); break; case "*": right = Convert.ToDouble(stack.Pop().value); left = Convert.ToDouble(stack.Pop().value); result = left * right; stack.Push(new Token(Token.TokenType.Operand, result.ToString())); break; case "/": right = Convert.ToDouble(stack.Pop().value); left = Convert.ToDouble(stack.Pop().value); result = left / right; stack.Push(new Token(Token.TokenType.Operand, result.ToString())); break; case "^": right = Convert.ToDouble(stack.Pop().value); left = Convert.ToDouble(stack.Pop().value); result = Math.Pow(left, right); stack.Push(new Token(Token.TokenType.Operand, result.ToString())); break; } } } return stack.Pop().value; } } }