Cod sursa(job #951449)

Utilizator SpiderManSimoiu Robert SpiderMan Data 20 mai 2013 16:57:41
Problema Evaluarea unei expresii Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 11.26 kb
# include <cstring>
# include <iostream>
# include <cmath>
# include <cstdlib>
# include <fstream>
# include <iomanip>
# include <tr1/unordered_map>
# include <string>
using namespace std;
using namespace tr1;

# define c(X) ((int) (X))

typedef long double ld;
const char *FIN = "evaluare.in", *FOU = "evaluare.out";
const int MAX = 100010, F_MAX = 171, P_MAX = 25, SIGMA = 26;
const ld PI = 4.0 * atan (1.0), e = 2.718281828459045;

ifstream f (FIN);
ofstream g (FOU);

unordered_map <string, ld> SG;

char S[MAX], *p = S;
ld F[F_MAX], P[P_MAX];

bool litera (char);
int vezi ();
bool check (char *X);
void init ();
ld deg_rad ();
ld rad_deg ();
ld subexp ();
ld fact ();
ld solve ();
ld f_abs ();
ld f_int ();
ld f_frac ();
ld sigma ();
ld pi_p ();
ld riemannsum ();
ld put ();
ld fib ();
ld _log();
ld _ln();
ld _log10();
ld _exp();
ld _lb();
ld _sqrt();
ld _root();
ld _sin();
ld _cos();
ld _tg();
ld _ctg();
ld _sec();
ld _csc();
ld _arcsin();
ld _arccos();
ld _arctg();
ld _arcctg();
ld _arcsec();
ld _arccsc();
ld _sinh();
ld _cosh();
ld _tgh();
ld _ctgh();
ld _sech();
ld _csch();
ld _arcsinh();
ld _arccosh();
ld _arctgh();
ld _arcctgh();
ld _arcsech();
ld _arccsch();
ld Cb ();
ld An ();
ld Pr ();

int main (void) {
    f.getline (S, MAX), init ();
    g << setprecision (10) << fixed << solve ();
}

void init () {
    F[0] = 1;
    for (int i = 1; i < F_MAX; ++i) {
        F[i] = i * F[i - 1];
    }
    for (int i = 0; i < P_MAX; ++i) {
        P[i] = pow (10.0, 1.0 * i);
    }
}

bool litera (char S) {
    return (S >= 'a' && S <= 'z') || (S >= 'A' && S <= 'Z');
}

ld solve () {
    ld r = subexp();

    while (*p == '+' || *p == '-')
        if (*p == '+')
            ++p, r += subexp();
        else if (*p == '-')
            ++p, r -= subexp();

    return r;
}

ld subexp () {
    ld r = put();

    while (*p == '*' || *p == '/' || *p == '%') {
        if (*p == '*')
            ++p, r *= put();
        else if (*p == '/')
            ++p, r /= put();
        else if (*p == '%')
            ++p, r = fmod (r, put());
    }

    return r;
}

ld put () {
    ld r = fact();

    while (*p == '^' || *p == '!') {
        if (*p == '^')
            ++p, r = pow (r, put ());
        else ++p, r = F[c(r)];
    }
    return r;
}

bool check (const char *X) {
    for (int i = 0, j = strlen (X); i < j; ++i) {
        if (*(p + i) != X[i]) {
            return 0;
        }
    }
    return 1;
}

ld fact () {
    ld r = 0;
    if (check ("(")) {
        ++p, r = solve(), ++p;
    } else if (check ("|")) {
        ++p, r = f_abs(), ++p;
    } else if (check ("[")) {
        ++p, r = f_int(), ++p;
    } else if (check ("{")) {
        ++p, r = f_frac(), ++p;
    } else if (check ("sigma(")) {
        p += 6, r = sigma(), ++p;
    } else if (check ("pi(")) {
        p += 3, r = pi_p(), ++p;
    } else if (check ("integrate(")) {
        p += 10, r = riemannsum (), ++p;
    } else if (check ("sin(")) {
        p += 4, r = _sin(), ++p;
    } else if (check ("cos(")) {
        p += 4, r = _cos(), ++p;
    } else if (check ("tg(")) {
        p += 3, r = _tg(), ++p;
    } else if (check ("ctg(")) {
        p += 4, r = _ctg(), ++p;
    } else if (check ("sec(")) {
        p += 4, r = _sec(), ++p;
    } else if (check ("csc(")) {
        p += 4, r = _csc(), ++p;
    } else if (check ("arcsin(")) {
        p += 7, r = _arcsin(), ++p;
    } else if (check ("arccos(")) {
        p += 7, r = _arccos(), ++p;
    } else if (check ("arctg(")) {
        p += 6, r = _arctg(), ++p;
    } else if (check ("arcctg(")) {
        p += 7, r = _arcctg(), ++p;
    } else if (check ("arcsec(")) {
        p += 7, r = _arcsec(), ++p;
    } else if (check ("arccsc(")) {
        p += 7, r = _arccsc(), ++p;
    } else if (check ("sinh(")) {
        p += 5, r = _sinh(), ++p;
    } else if (check ("cosh(")) {
        p += 5, r = _cosh(), ++p;
    } else if (check ("tgh(")) {
        p += 4, r = _tgh(), ++p;
    } else if (check ("ctgh(")) {
        p += 5, r = _ctgh(), ++p;
    } else if (check ("sech(")) {
        p += 5, r = _sech(), ++p;
    } else if (check ("csch(")) {
        p += 5, r = _csch(), ++p;
    } else if (check ("arcsinh(")) {
        p += 8, r = _arcsinh(), ++p;
    } else if (check ("arccosh(")) {
        p += 8, r = _arccosh(), ++p;
    } else if (check ("arctgh(")) {
        p += 7, r = _arctgh(), ++p;
    } else if (check ("arcctgh(")) {
        p += 8, r = _arcctgh(), ++p;
    } else if (check ("arcsech(")) {
        p += 8, r = _arcsech(), ++p;
    } else if (check ("arccsch(")) {
        p += 8, r = _arccsch(), ++p;
    } else if (check ("degree(")) {
        p += 7, r = rad_deg (), ++p;
    } else if (check ("radians(")) {
        p += 8, r = deg_rad (), ++p;
    } else if (check ("fib(")) {
        p += 4, r = fib (), ++p;
    } else if (check ("ln(")) {
        p += 3, r = _ln(), ++p;
    } else if (check ("lg(")) {
        p += 3, r = _log10(), ++p;
    } else if (check ("lb(")) {
        p += 3, r = _lb(), ++p;
    } else if (check ("log(")) {
        p += 4, r = _log(), ++p;
    } else if (check ("exp(")) {
        p += 4, r = _exp(), ++p;
    } else if (check ("sqrt(")) {
        p += 5, r = _sqrt(), ++p;
    } else if (check ("root(")) {
        p += 5, r = _root(), ++p;
    } else if (check ("C(")) {
        p += 2, r = Cb(), ++p;
    } else if (check ("A(")) {
        p += 2, r = An(), ++p;
    } else if (check ("P(")) {
        p += 2, r = Pr(), ++p;
    } else if (check ("pi")) {
        p += 2, r = PI;
    } else if (check ("e")) {
        ++p, r = e;
    } else {
        for (int vir = 0; (*p >= '0' && *p <= '9') || litera (*p) || *p == '.' || *p == '_'; ++p) {
            if (litera (*p) || *p == '_') {
                string arg = "";
                for (; litera (*p) || *p == '_'; arg += *p++);
                //if (SG.find (arg) == SG.end ()) probleme
                *p--, r += SG[arg];
            }
            else if (*p == '.') vir = 1;
            else if (vir == 0) r = r * 10 + *p - '0';
            else r += (*p - '0') / P[vir++];
        }
    }
    return r;
}

ld rad_deg () {
    ld r = solve ();
    return (r * 180) / PI;
}

ld deg_rad () {
    ld r = solve ();
    return (PI * r) / 180;
}

ld _sin() {
    ld r = solve ();
    return sin (r);
}

ld _cos() {
    ld r = solve ();
    return cos (r);
}

ld _tg() {
    ld r = solve ();
    return tan (r);
}

ld _ctg() {
    ld r = solve ();
    return 1.0 / tan (r);
}

ld _sec() {
    ld r = solve ();
    return 1.0 / cos (r);
}

ld _csc() {
    ld r = solve ();
    return 1.0 / sin (r);
}
// arc function
ld _arcsin() {
    ld r = solve ();
    return asin (r);
}

ld _arccos() {
    ld r = solve ();
    return acos (r);
}

ld _arctg() {
    ld r = solve ();
    return atan (r);
}

ld _arcctg() {
    ld r = solve ();
    return PI / 2.0 - atan (r);
}

ld _arcsec() {
    ld r = solve ();
    return acos (1.0 / r);
}

ld _arccsc() {
    ld r = solve ();
    return asin (1.0 / r);
}
// hyperbolic

ld _sinh() {
    ld r = solve ();
    return sinh (r);
}

ld _cosh() {
    ld r = solve ();
    return cosh (r);
}

ld _tgh() {
    ld r = solve ();
    return tanh (r);
}

ld _ctgh() {
    ld r = solve ();
    return 1.0 / tanh (r);
}

ld _sech() {
    ld r = solve ();
    return 1.0 / cosh (r);
}

ld _csch() {
    ld r = solve ();
    return 1.0 / sinh (r);
}
// arc hyperbolic
ld _arcsinh() {
    ld r = solve ();
    return log (r + sqrt (r * r + 1));
}

ld _arccosh() {
    ld r = solve ();
    return log (r + sqrt (r * r - 1));
}

ld _arctgh() {
    ld r = solve ();
    return 1.0 / 2.0 * log ((1.0 + r) / (1.0 - r));
}

ld _arcctgh() {
    ld r = solve ();
    return 1.0 / 2.0 * log ((r + 1.0) / (r - 1.0));
}

ld _arcsech() {
    ld r = 1.0 / solve ();
    return log (r + sqrt (r * r - 1));
}

ld _arccsch() {
    ld r = 1.0 / solve ();
    return log (r + sqrt (r * r + 1));
}

// stop trig

ld _log() {
    ld a, b;
    a = solve (), ++p, b = solve ();
    return log (b) / log (a);
}

ld _ln() {
    ld r = solve ();
    return log (r);
}

ld _log10() {
    ld r = solve ();
    return log10 (r);
}

ld _lb() {
    ld r = solve ();
    return log (r) / log (2);
}

ld _sqrt() {
    ld r = solve ();
    return sqrt (r);
}

ld _root() {
    ld r, grade;
    r = solve (), ++p, grade = solve (), ++p;
    return pow (r, 1.0 / grade);
}

ld _exp() {
    ld r = solve ();
    return exp (r);
}

ld f_abs () {
    ld r = solve ();
    return fabs (r);
}

ld f_int () {
    ld r = solve ();
    return floor (r);
}

ld f_frac () {
    ld r = solve ();
    return r - floor (r);
}

ld sigma () {
    int st, dr;
    ld r = 0;
    string arg = "";
    for (; *p != ','; arg += *p++);
    ++p, st = (int) solve (), ++p, dr = (int) solve (), ++p;
    int nr = vezi ();
    for (int i = st; i <= dr; ++i) {
        p -= nr;
        SG[arg] = i;
        r += solve ();
    }
    return r;
}

ld pi_p () {
    int st, dr;
    ld r = 1;
    string arg = "";
    for (; *p != ','; arg += *p++);
    ++p, st = (int) solve (), ++p, dr = (int) solve (), ++p;
    int nr = vezi ();
    for (int i = st; i <= dr; ++i) {
        p -= nr;
        SG[arg] = i;
        r *= solve ();
    }
    return r;
}

const ld subintervals = 10000;

ld riemannsum () { // definite integrals
    ld st, dr;
    string arg = "";
    for (; *p != ','; arg += *p++);
    ++p, st = solve (), ++p, dr = solve (), ++p;
    ld sum = 0.0, subint = (dr - st) / subintervals, alfa = st + subint / 2.0;
    int nr = vezi ();
    for (int k = 0; k < subintervals; ++k) {
        p -= nr;
        SG[arg] = alfa;
        sum += solve () * subint;
        alfa += subint;
    }
    return sum;
}

int vezi () {
    int nr = 0;
    for (int nr1 = 0; ; ++p, ++nr) {
        if (*p == '(') ++nr1;
        else if (*p == ')' && nr1 == 0) break;
        else if (*p == ')') --nr1;
    }
    return nr;
}

ld Cb () {
    ld r, rr;
    r = solve (), ++p, rr = solve ();
    return F[c(r)] / (F[c(rr)] * F[c(r - rr)]);
}

ld An () {
    ld r, rr;
    r = solve (), ++p, rr = solve ();
    return F[c(r)] / F[c(r - rr)];
}

ld Pr () {
    ld r;
    r = solve (), ++p;
    return F[c(r)];
}

int MOD, Z[2][2], M[2][2];

inline void mult (int A[2][2], int B[2][2]) {
    int C[2][2];
    for (int i = 0; i < 2; ++i) {
        for (int j = 0; j < 2; ++j) {
            C[i][j] = 0;
            for (int k = 0; k < 2; ++k) {
                C[i][j] += 1LL * A[i][k] * B[k][j] % MOD;
                if (C[i][j] >= MOD) C[i][j] -= MOD;
            }
        }
    }

    for (int i = 0; i < 2; ++i) {
        for (int j = 0; j < 2; ++j) {
            A[i][j] = C[i][j];
        }
    }
}

inline void powr (int P, int M[2][2]) {
    M[0][0] = M[1][1] = 1;

    for (; P; P >>= 1) {
        if (P & 1) {
            mult (M, Z);
        }

        mult (Z, Z);
    }
}

ld fib () {
    int N;
    N = (int) solve (), ++p, MOD = (int) solve ();

    Z[0][0] = 0, Z[0][1] = 1;
    Z[1][0] = 1, Z[1][1] = 1;

    powr (N - 1, M);
    return M[1][1];
}