#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include <stdio.h>

#define PI 3.14159265358979323846
#define E  2.71828182845904523536

typedef struct {
    double a; // Linear coefficient (for x)
    double b; // Constant term
} Term;

// Function Prototypes
Term parse_expression(const char** str);
Term parse_term(const char** str);
Term parse_factor(const char** str);

// Helper to skip whitespace
void skip_ws(const char** str) {
    while (**str && isspace(**str)) (*str)++;
}

// Advanced string matcher
int match(const char** str, const char* keyword) {
    skip_ws(str);
    size_t len = strlen(keyword);
    if (strncmp(*str, keyword, len) == 0) {
        // Ensure we aren't matching 'sin' inside 'sinusoidal'
        if (!isalnum((*str)[len])) {
            *str += len;
            return 1;
        }
    }
    return 0;
}

Term parse_factor(const char** str) {
    skip_ws(str);
    Term res = {0, 0};

    // 1. Handle Unary Operators
    if (**str == '-') {
        (*str)++;
        Term inner = parse_factor(str);
        res.a = -inner.a;
        res.b = -inner.b;
        return res;
    }
    if (**str == '+') {
        (*str)++;
        return parse_factor(str);
    }

    // 2. Handle Constants
    if (match(str, "pi")) { res.b = PI; }
    else if (match(str, "e")) { res.b = E; }
    
    // 3. Handle Functions
    else if (match(str, "sin"))  { res.b = sin(parse_factor(str).b); }
    else if (match(str, "cos"))  { res.b = cos(parse_factor(str).b); }
    else if (match(str, "tan"))  { res.b = tan(parse_factor(str).b); }
    else if (match(str, "sqrt")) { res.b = sqrt(parse_factor(str).b); }
    else if (match(str, "log"))  { res.b = log10(parse_factor(str).b); }
    else if (match(str, "ln"))   { res.b = log(parse_factor(str).b); }
    else if (match(str, "abs"))  { res.b = fabs(parse_factor(str).b); }
    else if (match(str, "exp"))  { res.b = exp(parse_factor(str).b); }

    // 4. Handle Parentheses
    else if (**str == '(') {
        (*str)++;
        res = parse_expression(str);
        if (**str == ')') (*str)++; // Crucial: Consume the closing paren
    }

    // 5. Handle Variables
    else if (**str == 'x' || **str == 'X') {
        (*str)++;
        res.a = 1.0;
    }

    // 6. Handle Numbers
    else if (isdigit(**str) || **str == '.') {
        char* end;
        res.b = strtod(*str, &end);
        *str = end;
    }

    // 7. Handle Post-Factor Implicit Multiplication (e.g., 2x, 5(x+1), sin(pi)x)
    skip_ws(str);
    if (**str == 'x' || **str == 'X') {
        (*str)++;
        res.a = res.b; // e.g., 2 becomes 2x
        res.b = 0;
    } else if (**str == '(') {
        // e.g., 2(x+1) -> parsed as 2 * (x+1)
        Term next = parse_factor(str);
        res.a = res.b * next.a;
        res.b = res.b * next.b;
    }

    return res;
}

Term parse_term(const char** str) {
    Term res = parse_factor(str);
    skip_ws(str);
    while (**str == '*' || **str == '/') {
        char op = *(*str)++;
        Term next = parse_factor(str);
        if (op == '*') {
            // Linear expansion: (a1x + b1) * b2 = (a1*b2)x + (b1*b2)
            // (Only supports multiplying by a constant to stay linear)
            res.a = res.a * next.b + next.a * res.b;
            res.b = res.b * next.b;
        } else {
            if (next.b != 0) {
                res.a /= next.b;
                res.b /= next.b;
            } else {
                res.a = NAN; res.b = NAN; 
            }
        }
        skip_ws(str);
    }
    return res;
}

Term parse_expression(const char** str) {
    Term res = parse_term(str);
    skip_ws(str);
    while (**str == '+' || **str == '-') {
        char op = *(*str)++;
        Term next = parse_term(str);
        if (op == '+') {
            res.a += next.a;
            res.b += next.b;
        } else {
            res.a -= next.a;
            res.b -= next.b;
        }
        skip_ws(str);
    }
    return res;
}

// The God-Tier Entry Point
double solve(const char* equation) {
    if (!equation || strlen(equation) == 0) return 0;

    const char* eq_ptr = strchr(equation, '=');
    
    // Case 1: Simple Evaluation (no '=')
    if (!eq_ptr) {
        const char* p = equation;
        Term result = parse_expression(&p);
        return result.b; 
    }

    // Case 2: Equation Solving
    // Split safely without massive buffers
    char left_buf[512] = {0};
    size_t left_len = eq_ptr - equation;
    if (left_len >= sizeof(left_buf)) left_len = sizeof(left_buf) - 1;
    strncpy(left_buf, equation, left_len);
    
    const char* right_side = eq_ptr + 1;
    const char* pL = left_buf;
    const char* pR = right_side;

    Term L = parse_expression(&pL);
    Term R = parse_expression(&pR);

    // Solve La*x + Lb = Ra*x + Rb  => (La - Ra)x = Rb - Lb
    double final_a = L.a - R.a;
    double final_b = R.b - L.b;

    if (fabs(final_a) < 1e-12) {
        return (fabs(final_b) < 1e-12) ? 0.0 : NAN; // Identity or Impossible
    }
    
    return final_b / final_a;
}