From 378a90c4bfeb1c06ba47a1db1ebc48e8894b4119 Mon Sep 17 00:00:00 2001 From: libd3d <106087255+libd3d@users.noreply.github.com> Date: Sat, 27 Dec 2025 22:11:04 +0000 Subject: [PATCH] code cleanup better trimming, case-insensitivity, cleaner structure --- Formula evaluator/Formula evaluator.cpp | 202 ++++++++++++++---------- 1 file changed, 120 insertions(+), 82 deletions(-) diff --git a/Formula evaluator/Formula evaluator.cpp b/Formula evaluator/Formula evaluator.cpp index b6f34ae..ceb159e 100644 --- a/Formula evaluator/Formula evaluator.cpp +++ b/Formula evaluator/Formula evaluator.cpp @@ -1,105 +1,143 @@ #include #include #include -#include #include +#include // for std::isspace, std::tolower +#include + using namespace std; +// trim whitespace from both ends +string trim(const string& str) { + size_t first = str.find_first_not_of(" \t\n\r"); + if (first == string::npos) + return ""; + + size_t last = str.find_last_not_of(" \t\n\r"); + return str.substr(first, last - first + 1); +} - auto trim = [](string& s) { - s.erase(remove_if(s.begin(), s.end(), ::isspace), s.end()); - }; +// remove all whitespace and parentheses, make lowercase +string normalize(const string& s) { + string result; + result.reserve(s.size()); - string trimz(const string& s) { - string result; - for (char c : s) { - if (!isspace(c) && c != '(' && c != ')') { - result.push_back(c); - } + for (char ch : s) { + if (!isspace(static_cast(ch)) && ch != '(' && ch != ')') { + result += tolower(static_cast(ch)); } - return result; } - vector splitFactors(const string & expr) { - vector parts; - string token; - stringstream ss(expr); - while (getline(ss, token, '*')) { - if (!token.empty()) parts.push_back(token); + return result; +} + +// split them by '*' and normalize each factor +vector split_and_normalize_factors(const string& expr) { + vector factors; + stringstream ss(expr); + string token; + + while (getline(ss, token, '*')) { + string cleaned = normalize(token); + if (!cleaned.empty()) { + factors.push_back(cleaned); } - return parts; } - //TODO: make it not case sensitive - int main() { - auto trim = [](string& s) { - s.erase(remove_if(s.begin(), s.end(), ::isspace), s.end()); - }; - string formula; - cout << "Enter a formula (e.g., R = (rho * L) / A):" << endl; - getline(cin, formula); - - string target; - cout << "Which variable do you want to isolate? "; - cin >> target; - - size_t eqPos = formula.find('='); - if (eqPos == string::npos) { - cout << "Invalid formula." << endl; - return 0; - } + return factors; +} - string left = trimz(formula.substr(0, eqPos)); - string right = trimz(formula.substr(eqPos + 1)); +string join_factors(const vector& factors, const string& sep = " * ") { + if (factors.empty()) return "1"; - if (left == target) { - cout << target << " = " << right << endl; - return 0; - } + string result = factors[0]; + for (size_t i = 1; i < factors.size(); ++i) { + result += sep + factors[i]; + } + return result; +} + +int main() { + string full_formula; + cout << "Enter formula (e.g. R = (rho * L) / A): "; + getline(cin, full_formula); + + string target; + cout << "Variable to isolate: "; + cin >> target; + cin.ignore(); // consume newline after cin >> + + // normalize target for comparison + string target_norm = normalize(target); + if (target_norm.empty()) { + cout << "Invalid variable name.\n"; + return 1; + } + + size_t eq_pos = full_formula.find('='); + if (eq_pos == string::npos) { + cout << "Formula must contain '=' sign.\n"; + return 1; + } + + string left_side = trim(full_formula.substr(0, eq_pos)); + string right_side = trim(full_formula.substr(eq_pos + 1)); - string numerator = right, denominator = "1"; - size_t divPos = right.find('/'); - if (divPos != string::npos) { - numerator = right.substr(0, divPos); - denominator = right.substr(divPos + 1); + string left_norm = normalize(left_side); + string right_norm = normalize(right_side); + + // early exit target is already on left + if (left_norm == target_norm) { + cout << target << " = " << right_side << "\n"; + return 0; + } + + // find division (only supported though) + size_t div_pos = right_side.find('/'); + string numerator_str = right_side; + string denominator_str = "1"; + + if (div_pos != string::npos) { + numerator_str = trim(right_side.substr(0, div_pos)); + denominator_str = trim(right_side.substr(div_pos + 1)); + } + + // get normalized factors + auto num_factors = split_and_normalize_factors(numerator_str); + auto den_factors = split_and_normalize_factors(denominator_str); + + // in numerator + auto it_num = find(num_factors.begin(), num_factors.end(), target_norm); + if (it_num != num_factors.end()) { + num_factors.erase(it_num); + + cout << target << " = " << left_side; + + if (!den_factors.empty()) { + cout << " * (" << join_factors(den_factors) << ")"; } - numerator = trimz(numerator); - denominator = trimz(denominator); - - vector numFactors = splitFactors(numerator); - vector denFactors = splitFactors(denominator); - - auto it = find(numFactors.begin(), numFactors.end(), target); - if (it != numFactors.end()) { - numFactors.erase(it); - cout << target << " = (" << left << " * " << denominator << ")"; - if (!numFactors.empty()) { - cout << " / ("; - for (size_t i = 0; i < numFactors.size(); i++) { - if (i > 0) cout << " * "; - cout << numFactors[i]; - } - cout << ")"; - } - cout << endl; - return 0; + if (!num_factors.empty()) { + cout << " / (" << join_factors(num_factors) << ")"; } - it = find(denFactors.begin(), denFactors.end(), target); - if (it != denFactors.end()) { - denFactors.erase(it); - cout << target << " = (" << numerator << ")"; - if (!denFactors.empty()) { - cout << " / ("; - for (size_t i = 0; i < denFactors.size(); i++) { - if (i > 0) cout << " * "; - cout << denFactors[i]; - } - cout << ")"; - } - cout << " / " << left << endl; - return 0; + cout << "\n"; + return 0; + } + + // target in denominator + auto it_den = find(den_factors.begin(), den_factors.end(), target_norm); + if (it_den != den_factors.end()) { + den_factors.erase(it_den); + + cout << target << " = (" << numerator_str << ")"; + + if (!den_factors.empty()) { + cout << " / (" << join_factors(den_factors) << ")"; } - cout << "Variable not found." << endl; + cout << " / " << left_side << "\n"; return 0; } + + cout << "Variable '" << target << "' not found in the formula.\n"; + return 1; +}