private static string GetOptimizedPostfixNotation(string Expression) {
Expression = " " + Expression + " ";
Expression = Expression.Replace(" 1 1 == -- ", " 0 ");
Expression = Expression.Replace(" 1 doors - 1 == -- ", " doors ! -- ");
string[] Arguments = Expression.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
string[] Stack = new string[Arguments.Length];
int StackLength = 0;
System.Globalization.CultureInfo Culture = System.Globalization.CultureInfo.InvariantCulture;
for (int i = 0; i < Arguments.Length; i++) {
switch (Arguments[i].ToLowerInvariant()) {
case "<>":
{
bool q = true;
if (StackLength >= 1) {
if (Stack[StackLength - 1] == "<>") {
// <> <>
// [n/a]
StackLength--;
q = false;
} else if (StackLength >= 2) {
double b;
if (double.TryParse(Stack[StackLength - 1], System.Globalization.NumberStyles.Float, Culture, out b)) {
double a;
if (double.TryParse(Stack[StackLength - 2], System.Globalization.NumberStyles.Float, Culture, out a)) {
// a b <>
// b a
string t = Stack[StackLength - 1];
Stack[StackLength - 1] = Stack[StackLength - 2];
Stack[StackLength - 2] = t;
}
}
}
}
if (q) {
Stack[StackLength] = Arguments[i];
StackLength++;
}
} break;
case "+":
{
bool q = true;
if (StackLength >= 2) {
double b;
if (double.TryParse(Stack[StackLength - 1], System.Globalization.NumberStyles.Float, Culture, out b)) {
double a;
if (double.TryParse(Stack[StackLength - 2], System.Globalization.NumberStyles.Float, Culture, out a)) {
// x y +
// (x y +)
Stack[StackLength - 2] = (a + b).ToString(Culture);
StackLength--;
q = false;
} else if (StackLength >= 3 && Stack[StackLength - 2] == "+") {
if (double.TryParse(Stack[StackLength - 3], System.Globalization.NumberStyles.Float, Culture, out a)) {
// A x + y +
// A (y x +) +
Stack[StackLength - 3] = (a + b).ToString(Culture);
StackLength--;
q = false;
}
} else if (StackLength >= 3 && Stack[StackLength - 2] == "-") {
if (double.TryParse(Stack[StackLength - 3], System.Globalization.NumberStyles.Float, Culture, out a)) {
// A x - y +
// A (y x -) +
Stack[StackLength - 3] = (b - a).ToString(Culture);
Stack[StackLength - 2] = "+";
StackLength--;
q = false;
}
} else if (Stack[StackLength - 2] == "*") {
// A x * y +
// A x y fma
Stack[StackLength - 2] = Stack[StackLength - 1];
Stack[StackLength - 1] = "fma";
q = false;
} else if (Stack[StackLength - 2] == "fma") {
if (double.TryParse(Stack[StackLength - 3], System.Globalization.NumberStyles.Float, Culture, out a)) {
// A B y fma z +
// A B (y z +) fma
Stack[StackLength - 3] = (a + b).ToString(Culture);
StackLength--;
q = false;
}
}
}
}
if (q) {
Stack[StackLength] = Arguments[i];
StackLength++;
}
} break;
case "-":
{
bool q = true;
if (StackLength >= 2) {
double b;
if (double.TryParse(Stack[StackLength - 1], System.Globalization.NumberStyles.Float, Culture, out b)) {
double a;
if (double.TryParse(Stack[StackLength - 2], System.Globalization.NumberStyles.Float, Culture, out a)) {
// x y -
// (x y -)
Stack[StackLength - 2] = (a - b).ToString(Culture);
StackLength--;
q = false;
} else if (StackLength >= 3 && Stack[StackLength - 2] == "+") {
if (double.TryParse(Stack[StackLength - 3], System.Globalization.NumberStyles.Float, Culture, out a)) {
// A x + y -
// A (x y -) +
Stack[StackLength - 3] = (a - b).ToString(Culture);
Stack[StackLength - 2] = "+";
StackLength--;
q = false;
}
} else if (StackLength >= 3 && Stack[StackLength - 2] == "-") {
if (double.TryParse(Stack[StackLength - 3], System.Globalization.NumberStyles.Float, Culture, out a)) {
// A x - y -
// A (x y + minus) -
Stack[StackLength - 3] = (-a - b).ToString(Culture);
Stack[StackLength - 2] = "+";
StackLength--;
q = false;
}
} else if (Stack[StackLength - 2] == "*") {
// A x * y -
// A x (y minus) fma
Stack[StackLength - 2] = (-b).ToString(Culture);
Stack[StackLength - 1] = "fma";
q = false;
} else if (Stack[StackLength - 2] == "fma") {
if (double.TryParse(Stack[StackLength - 3], System.Globalization.NumberStyles.Float, Culture, out a)) {
// A B y fma z -
// A B (y z -) fma
Stack[StackLength - 3] = (a - b).ToString(Culture);
StackLength--;
q = false;
}
}
}
}
if (q) {
Stack[StackLength] = Arguments[i];
StackLength++;
}
} break;
case "minus":
{
bool q = true;
if (StackLength >= 1) {
if (Stack[StackLength - 1].Equals("minus", StringComparison.InvariantCultureIgnoreCase)) {
// minus minus
// [n/a]
StackLength--;
q = false;
} else {
double a;
if (double.TryParse(Stack[StackLength - 1], System.Globalization.NumberStyles.Float, Culture, out a)) {
// x minus
// (x minus)
Stack[StackLength - 1] = (-a).ToString(Culture);
q = false;
}
}
}
if (q) {
Stack[StackLength] = Arguments[i];
StackLength++;
}
} break;
case "*":
{
bool q = true;
if (StackLength >= 2) {
double b;
if (double.TryParse(Stack[StackLength - 1], System.Globalization.NumberStyles.Float, Culture, out b)) {
double a;
if (double.TryParse(Stack[StackLength - 2], System.Globalization.NumberStyles.Float, Culture, out a)) {
// x y *
// (x y *)
Stack[StackLength - 2] = (a * b).ToString(Culture);
StackLength--;
q = false;
} else if (StackLength >= 3 && Stack[StackLength - 2] == "*") {
if (double.TryParse(Stack[StackLength - 3], System.Globalization.NumberStyles.Float, Culture, out a)) {
// A x * y *
// A (x y *) *
Stack[StackLength - 3] = (a * b).ToString(Culture);
StackLength--;
q = false;
}
} else if (StackLength >= 3 && Stack[StackLength - 2] == "+") {
if (double.TryParse(Stack[StackLength - 3], System.Globalization.NumberStyles.Float, Culture, out a)) {
// A x + y *
// A y (x y *) fma
Stack[StackLength - 3] = Stack[StackLength - 1];
Stack[StackLength - 2] = (a * b).ToString(Culture);
Stack[StackLength - 1] = "fma";
q = false;
}
} else if (StackLength >= 3 && Stack[StackLength - 2] == "-") {
if (double.TryParse(Stack[StackLength - 3], System.Globalization.NumberStyles.Float, Culture, out a)) {
// A x - y *
// A y (x y * minus) fma
Stack[StackLength - 3] = Stack[StackLength - 1];
Stack[StackLength - 2] = (-a * b).ToString(Culture);
Stack[StackLength - 1] = "fma";
q = false;
}
} else if (StackLength >= 4 && Stack[StackLength - 2] == "fma") {
if (double.TryParse(Stack[StackLength - 3], System.Globalization.NumberStyles.Float, Culture, out a)) {
double c;
if (double.TryParse(Stack[StackLength - 4], System.Globalization.NumberStyles.Float, Culture, out c)) {
// A x y fma z *
// A (x z *) (y z *) fma
Stack[StackLength - 4] = (c * b).ToString(Culture);
Stack[StackLength - 3] = (a * b).ToString(Culture);
StackLength--;
q = false;
} else {
// A B y fma z *
// A B * z (y z *) fma
Stack[StackLength - 3] = "*";
Stack[StackLength - 2] = Stack[StackLength - 1];
Stack[StackLength - 1] = (a * b).ToString(Culture);
Stack[StackLength] = "fma";
StackLength++;
q = false;
}
}
}
}
}
if (q) {
Stack[StackLength] = Arguments[i];
StackLength++;
}
} break;
case "reciprocal":
{
bool q = true;
if (StackLength >= 1) {
if (Stack[StackLength - 1].Equals("reciprocal", StringComparison.InvariantCultureIgnoreCase)) {
// reciprocal reciprocal
// [n/a]
StackLength--;
q = false;
} else {
double a;
if (double.TryParse(Stack[StackLength - 1], System.Globalization.NumberStyles.Float, Culture, out a)) {
// x reciprocal
// (x reciprocal)
a = a == 0.0 ? 0.0 : 1.0 / a;
Stack[StackLength - 1] = a.ToString(Culture);
q = false;
}
}
}
if (q) {
Stack[StackLength] = Arguments[i];
StackLength++;
}
} break;
case "/":
{
bool q = true;
if (StackLength >= 2) {
double b;
if (double.TryParse(Stack[StackLength - 1], System.Globalization.NumberStyles.Float, Culture, out b)) {
if (b != 0.0) {
double a;
if (double.TryParse(Stack[StackLength - 2], System.Globalization.NumberStyles.Float, Culture, out a)) {
// x y /
// (x y /)
Stack[StackLength - 2] = (a / b).ToString(Culture);
StackLength--;
q = false;
} else if (StackLength >= 3 && Stack[StackLength - 2] == "*") {
if (double.TryParse(Stack[StackLength - 3], System.Globalization.NumberStyles.Float, Culture, out a)) {
// A x * y /
// A (x y /) *
Stack[StackLength - 3] = (a / b).ToString(Culture);
StackLength--;
q = false;
}
}
}
}
}
if (q) {
Stack[StackLength] = Arguments[i];
StackLength++;
}
} break;
case "++":
{
bool q = true;
if (StackLength >= 1) {
double a;
if (double.TryParse(Stack[StackLength - 1], System.Globalization.NumberStyles.Float, Culture, out a)) {
// x ++
// (x ++)
Stack[StackLength - 1] = (a + 1).ToString(Culture);
q = false;
}
}
if (q) {
Stack[StackLength] = Arguments[i];
StackLength++;
}
} break;
case "--":
{
bool q = true;
if (StackLength >= 1) {
double a;
if (double.TryParse(Stack[StackLength - 1], System.Globalization.NumberStyles.Float, Culture, out a)) {
// x --
// (x --)
Stack[StackLength - 1] = (a - 1).ToString(Culture);
q = false;
}
}
if (q) {
Stack[StackLength] = Arguments[i];
StackLength++;
}
} break;
case "!":
{
bool q = true;
if (StackLength >= 1) {
if (Stack[StackLength - 1] == "!") {
StackLength--;
q = false;
} else if (Stack[StackLength - 1] == "==") {
Stack[StackLength - 1] = "!=";
q = false;
} else if (Stack[StackLength - 1] == "!=") {
Stack[StackLength - 1] = "==";
q = false;
} else if (Stack[StackLength - 1] == "<") {
Stack[StackLength - 1] = ">=";
q = false;
} else if (Stack[StackLength - 1] == ">") {
Stack[StackLength - 1] = "<=";
q = false;
} else if (Stack[StackLength - 1] == "<=") {
Stack[StackLength - 1] = ">";
q = false;
} else if (Stack[StackLength - 1] == ">=") {
Stack[StackLength - 1] = "<";
q = false;
} else {
double a;
if (double.TryParse(Stack[StackLength - 1], System.Globalization.NumberStyles.Float, Culture, out a)) {
Stack[StackLength - 1] = a == 0.0 ? "1" : "0";
q = false;
}
}
}
if (q) {
Stack[StackLength] = Arguments[i];
StackLength++;
}
} break;
case "==":
{
bool q = true;
if (StackLength >= 2) {
double b;
if (double.TryParse(Stack[StackLength - 1], System.Globalization.NumberStyles.Float, Culture, out b)) {
double a;
if (double.TryParse(Stack[StackLength - 2], System.Globalization.NumberStyles.Float, Culture, out a)) {
Stack[StackLength - 2] = a == b ? "1" : "0";
StackLength--;
q = false;
}
}
}
if (q) {
Stack[StackLength] = Arguments[i];
StackLength++;
}
} break;
case "!=":
{
bool q = true;
if (StackLength >= 2) {
double b;
if (double.TryParse(Stack[StackLength - 1], System.Globalization.NumberStyles.Float, Culture, out b)) {
double a;
if (double.TryParse(Stack[StackLength - 2], System.Globalization.NumberStyles.Float, Culture, out a)) {
Stack[StackLength - 2] = a != b ? "1" : "0";
StackLength--;
q = false;
}
}
}
if (q) {
Stack[StackLength] = Arguments[i];
StackLength++;
}
} break;
case "<":
{
bool q = true;
if (StackLength >= 2) {
double b;
if (double.TryParse(Stack[StackLength - 1], System.Globalization.NumberStyles.Float, Culture, out b)) {
double a;
if (double.TryParse(Stack[StackLength - 2], System.Globalization.NumberStyles.Float, Culture, out a)) {
Stack[StackLength - 2] = a < b ? "1" : "0";
StackLength--;
q = false;
}
}
}
if (q) {
Stack[StackLength] = Arguments[i];
StackLength++;
}
} break;
case ">":
{
bool q = true;
if (StackLength >= 2) {
double b;
if (double.TryParse(Stack[StackLength - 1], System.Globalization.NumberStyles.Float, Culture, out b)) {
double a;
if (double.TryParse(Stack[StackLength - 2], System.Globalization.NumberStyles.Float, Culture, out a)) {
Stack[StackLength - 2] = a > b ? "1" : "0";
StackLength--;
q = false;
}
}
}
if (q) {
Stack[StackLength] = Arguments[i];
StackLength++;
}
} break;
case "<=":
{
bool q = true;
if (StackLength >= 2) {
double b;
if (double.TryParse(Stack[StackLength - 1], System.Globalization.NumberStyles.Float, Culture, out b)) {
double a;
if (double.TryParse(Stack[StackLength - 2], System.Globalization.NumberStyles.Float, Culture, out a)) {
Stack[StackLength - 2] = a <= b ? "1" : "0";
StackLength--;
q = false;
}
}
}
if (q) {
Stack[StackLength] = Arguments[i];
StackLength++;
}
} break;
case ">=":
{
bool q = true;
if (StackLength >= 2) {
double b;
if (double.TryParse(Stack[StackLength - 1], System.Globalization.NumberStyles.Float, Culture, out b)) {
double a;
if (double.TryParse(Stack[StackLength - 2], System.Globalization.NumberStyles.Float, Culture, out a)) {
Stack[StackLength - 2] = a >= b ? "1" : "0";
StackLength--;
q = false;
}
}
}
if (q) {
Stack[StackLength] = Arguments[i];
StackLength++;
}
} break;
case "floor":
if (StackLength >= 1 && Stack[StackLength - 1] == "/") {
Stack[StackLength - 1] = "quotient";
} else {
Stack[StackLength] = Arguments[i];
StackLength++;
} break;
default:
Stack[StackLength] = Arguments[i];
StackLength++;
break;
}
}
System.Text.StringBuilder Builder = new System.Text.StringBuilder();
for (int i = 0; i < StackLength; i++) {
if (i != 0) Builder.Append(' ');
Builder.Append(Stack[i]);
}
return Builder.ToString();
}