Cod sursa(job #951414)

Utilizator SpiderManSimoiu Robert SpiderMan Data 20 mai 2013 15:04:18
Problema Evaluarea unei expresii Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 9.25 kb
# include <cstring>
# include <cmath>
# include <cstdlib>
# include <fstream>
# include <iomanip>
# include <tr1/unordered_map>
using namespace std ;
using namespace tr1;

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

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

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

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

bool litera (char);
int vezi ();
bool check ( char *X ) ;
void init ();
ld subexp ();
ld fact ();
ld solve ();
ld f_abs ();
ld f_int ();
ld f_frac ();
ld sigma ();
ld pi_p ();
ld put ();
ld _log();
ld _ln();
ld _log10();
ld _exp();
ld _lb();
ld _sqrt();
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 (0) << 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 () {
    int 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 ( "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 ( "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 ( "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 ) {
            if ( litera (*p) ) r = r * 10 + SG[c(*p)];
            else if ( *p == '.' ) vir = 1 ;
            else if ( vir == 0 ) r = r * 10 + *p - '0';
            else r += (*p - '0') / P[vir++] ;
        }
    }
    return r;
}

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 _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 ;
    char ch = *p++;
    ++p, st = (int) solve (), ++p, dr = (int) solve (), ++p ;
    int nr = vezi () ;
    for ( int i = st; i <= dr; ++i ) {
        p -= nr ;
        SG[c(ch)] = i ;
        r += solve () ;
    }
    return r ;
}

ld pi_p () {
    int st, dr ;
    ld r = 1 ;
    char ch = *p++;
    ++p, st = (int) solve (), ++p, dr = (int) solve (), ++p ;
    int nr = vezi () ;
    for ( int i = st; i <= dr; ++i ) {
        p -= nr ;
        SG[c(ch)] = i ;
        r *= solve () ;
    }
    return r ;
}

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)] ;
}