Compare commits

...

3 Commits

Author SHA1 Message Date
cb5762a3fe Calculator works 2025-05-18 16:17:14 -05:00
45f1d0f69d Calculator 2025-05-13 15:35:41 -05:00
dffca865dc spellcheck 2025-05-13 08:35:22 -05:00
2 changed files with 201 additions and 84 deletions

View File

@@ -43,90 +43,199 @@ void Calculator::run() {
} }
} }
void Calculator::index(std::string equation, std::unordered_map<unsigned int, std::string>& nodes) {
unsigned int idx = 0;
std::string calculate(std::string equation) { nodes.clear();
std::stringstream s(equation);
const static std::string operators[] = {
"(",
")",
"^",
"*",
"/",
"+",
"-"
};
for(const std::string& s : operators) {
while(equation.find(s, idx) != std::string::npos) {
int next = equation.find(s, idx);
nodes[next] = equation.substr(next, s.length());
idx = next + s.length();
}
idx = 0;
}
// -3+8*6-(8+4)^9/5
for(unsigned int i = 0; i < equation.length(); i++) {
static unsigned int begin = 0, end = 0;
if(nodes.find(i) == nodes.end()) {
if(nodes.find(i - 1) != nodes.end() || i == 0) {
//first digit of expression
begin = i;
}
if(nodes.find(i + 1) != nodes.end() || i == equation.length() - 1) {
//character after last digit of expression
end = i + 1;
nodes[begin] = equation.substr(begin, end - begin);
nodes[end - 1] = equation.substr(begin, end - begin);
}
}
}
}
double Calculator::evaluate(std::string equation, std::unordered_map<char, std::string>& evalStr) {
char op = '^';
while(equation.find(op) == std::string::npos) {
switch(op) {
case '^':
op = '*';
break;
case '*':
op = '/';
break;
case '/':
op = '+';
break;
case '+':
op = '-';
break;
case '-':
//no operator
if(evalStr.find(equation.front()) != evalStr.end()) {
return evaluate(evalStr[equation.front()], evalStr);
} else {
return std::stod(equation);
}
break;
}
}
//op is now the appropriate operator
//if either term is a placeholder, evaluate and substitute.
double a, b;
if(evalStr.find(equation.front()) != evalStr.end()) {
a = evaluate(evalStr[equation.front()], evalStr);
} else {
if(equation.find(op) == 0 && op == '-') {
a = 0;
} else {
a = std::stod(equation.substr(0, equation.find(op)));
}
}
if(evalStr.find(equation.back()) != evalStr.end()) {
b = evaluate(evalStr[equation.back()], evalStr);
} else {
b = std::stod(equation.substr(equation.find(op) + 1));
}
switch(op) {
case '^':
return pow(a, b);
case '*':
return a * b;
case '/':
return a / b;
case '+':
return a + b;
case '-':
return a - b;
}
}
std::string Calculator::calculate(std::string equation) {
//PEMDAS //PEMDAS
while(equation.find('(') != std::string::npos) { while(equation.find(' ') != std::string::npos) {
if(equation.find(')') == std::string::npos) { equation.erase(equation.find(' '), 1);
return "error";
}
int start = equation.find_last_of('(');
int end = equation.find_first_of(')', start);
std::string insert = calculate(equation.substr(start + 1, end - 1));
equation.replace(start, end, insert.c_str());
} }
while(equation.find('^') != std::string::npos) { std::unordered_map<unsigned int, std::string> nodes;
std::unordered_map<char, std::string> evalStr;
std::string eval = "a";
unsigned int idx = 0;
index(equation, nodes);
idx = 0;
// ()
while(equation.find(')', idx) != std::string::npos) {
int end = equation.find(')');
int begin = equation.rfind('(', end);
evalStr[eval.front()] = calculate(equation.substr(begin + 1, (end - begin) - 1));
equation.replace(begin, (end - begin) + 1, eval);
eval.front()++;
idx = end + 1;
}
idx = 0;
index(equation, nodes);
// ^
while(equation.find('^', idx) != std::string::npos) {
int mid = equation.find('^'); int mid = equation.find('^');
int start = equation.rfind(' ', mid - 1); int begin = equation.find(nodes[mid - 1] + nodes[mid]);
int end = equation.find(' ', mid + 1); int end = equation.find(nodes[mid] + nodes[mid + 1], begin) + (nodes[mid] + nodes[mid + 1]).length();
double base = stod(equation.substr(start + 1, mid - 1)); evalStr[eval.front()] = equation.substr(begin, end - begin);
double exp = stod(equation.substr(mid + 1, end - 1)); equation.replace(begin, end - begin, eval);
eval.front()++;
std::string insert = std::to_string(pow(base, exp)); idx = end + 1;
equation.replace(start, end, insert.c_str());
} }
while(equation.find('*') != std::string::npos) { idx = 0;
int mid = equation.find('*'); index(equation, nodes);
int start = equation.rfind(' ', mid - 1); // * or /
int end = equation.find(' ', mid + 1); while(equation.find('*', idx) != std::string::npos || equation.find('/', idx) != std::string::npos) {
double a = stod(equation.substr(start + 1, mid - 1)); if(equation.find('*', idx) < equation.find('/', idx) && equation.find('*', idx) != std::string::npos) {
double b = stod(equation.substr(mid + 1, end - 1)); int mid = equation.find('*');
int begin = equation.find(nodes[mid - 1] + nodes[mid]);
std::string insert = std::to_string(a * b); int end = equation.find(nodes[mid] + nodes[mid + 1], begin) + (nodes[mid] + nodes[mid + 1]).length();
evalStr[eval.front()] = equation.substr(begin, end - begin);
equation.replace(start, end, insert.c_str()); equation.replace(begin, end - begin, eval);
eval.front()++;
} idx = end + 1;
while(equation.find('/') != std::string::npos) { } else if(equation.find('/', idx) != std::string::npos) {
int mid = equation.find('/'); int mid = equation.find('/');
int start = equation.rfind(' ', mid - 1); int begin = equation.find(nodes[mid - 1] + nodes[mid]);
int end = equation.find(' ', mid + 1); int end = equation.find(nodes[mid] + nodes[mid + 1], begin) + (nodes[mid] + nodes[mid + 1]).length();
double a = stod(equation.substr(start + 1, mid - 1)); evalStr[eval.front()] = equation.substr(begin, end - begin);
double b = stod(equation.substr(mid + 1, end - 1)); equation.replace(begin, end - begin, eval);
eval.front()++;
std::string insert = std::to_string(a / b); idx = end + 1;
equation.replace(start, end, insert.c_str());
}
while(equation.find('+') != std::string::npos) {
int mid = equation.find('+');
int start = equation.rfind(' ', mid - 1);
int end = equation.find(' ', mid + 1);
double a = stod(equation.substr(start + 1, mid - 1));
double b = stod(equation.substr(mid + 1, end - 1));
std::string insert = std::to_string(a + b);
equation.replace(start, end, insert.c_str());
}
while(equation.find('-') != std::string::npos) {
int mid = equation.find('-');
int start = equation.rfind(' ', mid - 1);
if(start == std::string::npos) {
break;
} }
int end = equation.find(' ', mid + 1);
double a = stod(equation.substr(start + 1, mid - 1));
double b = stod(equation.substr(mid + 1, end - 1));
std::string insert = std::to_string(a - b);
equation.replace(start, end, insert.c_str());
} }
idx = 0;
return equation; index(equation, nodes);
// + or -
while(equation.find('+', idx) != std::string::npos || equation.find('-', idx) != std::string::npos) {
if(equation.find('+', idx) < equation.find('-', idx) && equation.find('+', idx) != std::string::npos) {
int mid = equation.find('+');
int begin = equation.find(nodes[mid - 1] + nodes[mid]);
int end = equation.find(nodes[mid] + nodes[mid + 1], begin) + (nodes[mid] + nodes[mid + 1]).length();
evalStr[eval.front()] = equation.substr(begin, end - begin);
equation.replace(begin, end - begin, eval);
eval.front()++;
idx = end + 1;
} else if(equation.find('-', idx) != std::string::npos) {
int mid = equation.find('-');
int begin = mid;
if(nodes.find(mid - 1) != nodes.end()) {
begin = equation.find(nodes[mid - 1] + nodes[mid]);
}
int end = equation.find(nodes[mid] + nodes[mid + 1], begin) + (nodes[mid] + nodes[mid + 1]).length();
evalStr[eval.front()] = equation.substr(begin, end - begin);
equation.replace(begin, end - begin, eval);
eval.front()++;
idx = end + 1;
}
}
return std::to_string(evaluate(equation, evalStr));
} }
@@ -145,8 +254,9 @@ void Calculator::basicCalculator() {
ImGui::BeginGroup(); ImGui::BeginGroup();
{ {
if(ImGui::Button("AC")) { if(ImGui::Button("AC")) {
s += " + "; s.clear();
} }
ImGui::SameLine();
if(ImGui::Button("()")) { if(ImGui::Button("()")) {
if(parenthesis) { if(parenthesis) {
@@ -157,9 +267,11 @@ void Calculator::basicCalculator() {
parenthesis = !parenthesis; parenthesis = !parenthesis;
} }
ImGui::SameLine();
if(ImGui::Button("Gr")) { if(ImGui::Button("Gr")) {
graphing = true; graphing = true;
} }
ImGui::SameLine();
if(ImGui::Button("=")) { if(ImGui::Button("=")) {
s = calculate(s); s = calculate(s);
} }
@@ -190,15 +302,17 @@ void Calculator::basicCalculator() {
} }
ImGui::SameLine(); ImGui::SameLine();
if(ImGui::Button("del")) { if(ImGui::Button("del")) {
if(s.back() == ' ') { if(!s.empty()) {
s.pop_back(); if(s.back() == ' ') {
if(s.back() == '(' || s.back() == ')') { s.pop_back();
parenthesis = !parenthesis; if(s.back() == '(' || s.back() == ')') {
parenthesis = !parenthesis;
}
s.pop_back();
s.pop_back();
} else {
s.pop_back();
} }
s.pop_back();
s.pop_back();
} else {
s.pop_back();
} }
} }
} }

View File

@@ -22,8 +22,11 @@ class Calculator : public Archimedes::Module {
void basicCalculator(); void basicCalculator();
std::string calculate(std::string); std::string calculate(std::string);
double evaluate(std::string, std::unordered_map<char, std::string>&);
void index(std::string, std::unordered_map<unsigned int, std::string>&);
void graphingCalculator(); void graphingCalculator();
}; };
#ifdef CALCULATOR_DYNAMIC #ifdef CALCULATOR_DYNAMIC