/
Algebra.cs
145 lines (142 loc) · 3.81 KB
/
Algebra.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Basic2D {
public static class Algebra {
public static string Do(string operation) {
Calc c = new Calc();
int parenDepth = 0;
int parenStart = 0;
for (int i = 0; i < operation.Length; i++) {
if (operation[i] == '(') {
parenDepth++;
if (parenDepth == 1) {
parenStart = i;
}
}
if (operation[i] == ')') {
parenDepth--;
if (parenDepth == 0) {
var newOp = operation.Substring(parenStart + 1, i - parenStart - 1);
var ans = Algebra.Do(newOp);
operation = operation.Substring(0, parenStart) + ans + operation.Substring(i + 1);
i = 0;
}
}
}
for (int i = 0; i < operation.Length; i++) {
if (operation[i] == '/') {
object leftVal;
object rightVal;
GetVals(operation, i, out leftVal, out rightVal);
operation = PatchOperation(operation, i, ((int)leftVal / (int)rightVal).ToString());
i = 0;
}
if (operation[i] == '*') {
object leftVal;
object rightVal;
GetVals(operation, i, out leftVal, out rightVal);
operation = PatchOperation(operation, i, ((int)leftVal * (int)rightVal).ToString());
i = 0;
}
}
for (int i = 0; i < operation.Length; i++) {
if (operation[i] == '+') {
object leftVal;
object rightVal;
GetVals(operation, i, out leftVal, out rightVal);
if (leftVal.GetType() == typeof(int)) {
operation = PatchOperation(operation, i, ((int)leftVal + (int)rightVal).ToString());
}
else {
leftVal = DeString((string)leftVal);
rightVal = DeString((string)rightVal);
operation = PatchOperation(operation, i, (string)leftVal + (string)rightVal);
}
i = 0;
}
if (operation[i] == '-') {
object leftVal;
object rightVal;
GetVals(operation, i, out leftVal, out rightVal);
operation = PatchOperation(operation, i, ((int)leftVal - (int)rightVal).ToString());
i = 0;
}
}
try {
return operation;
}
catch {
return Program.Vars[operation].ToString();
}
}
private static string DeString(string str) {
return str.Substring(1, str.Length - 2);
}
private static string PatchOperation(string operation, int i, string dat) {
if (countOperators(operation) >= 2) {
operation = operation.Substring(0, getLeftBound(operation, i) == 0 ? getLeftBound(operation, i) : getLeftBound(operation, i) + 1) + dat + operation.Substring(getRightBound(operation, i));
}
else {
operation = dat.ToString();
}
return operation;
}
private static void GetVals(string operation, int i, out object leftVal, out object rightVal) {
var leftString = operation.Substring(getLeftBound(operation, i), i - getLeftBound(operation, i));
var rightString = operation.Substring(i + 1, getRightBound(operation, i) - i - 1);
try {
leftVal = Int32.Parse(leftString);
}
catch {
leftVal = Program.Vars[leftString];
}
try {
rightVal = Int32.Parse(rightString);
}
catch {
rightVal = Program.Vars[rightString];
}
}
private static int getLeftBound(string s, int root) {
root--;
for (int i = root; i >= 0; i--) {
if (isBound(s[i])) {
return i;
}
}
return 0;
}
private static int getRightBound(string s, int root) {
root++;
for (int i = root; i < s.Length; i++) {
if (isBound(s[i])) {
return i;
}
}
return s.Length;
}
private static int countOperators(string s) {
int j = 0;
for (int i = 0; i < s.Length; i++) {
if (isBound(s[i])) {
j++;
}
}
return j;
}
private static bool isBound(char c) {
return c == ')' ||
c == '(' ||
c == '+' ||
c == '/' ||
c == '*' ||
c == '-';
}
}
public class Calc {
public List<Calc> SubCalcs = new List<Calc>();
}
}