Cod sursa(job #1515752)

Utilizator TiberiuDTiberiu Danciu TiberiuD Data 2 noiembrie 2015 09:39:40
Problema Bool Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.66 kb
#include <iostream>
#include <fstream>
#include <cstring>

using namespace std;

bool evalueazaExpresie(char expresie[], bool variabile[], int start, int sfarsit);
bool evalueazaAND(char expresie[], bool variabile[], int start, int sfarsit);
bool evalueazaNOT(char expresie[], bool variabile[], int start, int sfarsit);
bool evalueazaPAR(char expresie[], bool variabile[], int start, int sfarsit);
bool evalueazaVAR(char expresie[], bool variabile[], int start, int sfarsit);

void scoateSpatii(char expresie[]) {
    char *ptr = strstr(expresie, " ");
    int lungime = strlen(expresie);

    while(ptr != NULL && ptr - expresie < lungime) {
        char buf[1024];
        strcpy(buf, ptr + 1);
        strcpy(ptr, buf);

        ptr = strstr(expresie, " ");
        lungime = strlen(expresie);
    }
}

void schimba(char expresie[], char initial[], char caracter) {
    char *ptr = strstr(expresie, initial);
    int lungime = strlen(expresie);

    while(ptr != NULL && ptr - expresie < lungime) {
        expresie[ptr - expresie] = caracter;

        char buf[1024];
        strcpy(buf, ptr + strlen(initial));
        strcpy(ptr + 1, buf);

        ptr = strstr(expresie, initial);
        lungime = strlen(expresie);
    }
}

int main() {
    ifstream in("bool.in");
    ofstream out("bool.out");

    if(!in || !out)
        return 1;

    char expresie[1024];
    bool variabile[28] = {};
    int n;

    in.get(expresie, 1001);
    in >> n;

    schimba(expresie, "OR", '|');
    schimba(expresie, "AND", '&');
    schimba(expresie, "NOT", '!');
    schimba(expresie, "TRUE", '1');
    schimba(expresie, "FALSE", '0');
    scoateSpatii(expresie);

    for(int i = 1; i <= n; i++) {
        char var;
        in >> var;

        variabile[var - 'A'] = !variabile[var - 'A'];

        out << evalueazaExpresie(expresie, variabile, 0, strlen(expresie));
    }

    in.close();
    out.close();
    return 0;
}

bool evalueazaExpresie(char expresie[], bool variabile[], int start, int sfarsit) {
    int paranteze = 0, ultimaPozitie = start;

    bool subExpresii[1000];
    int nSubExp = 0;

    for(int i = ultimaPozitie; i < sfarsit; i++) {
        if(expresie[i] == '(')
            paranteze++;
        else if(expresie[i] == ')')
            paranteze--;

        if(paranteze == 0 && i <= sfarsit - 1)
            if(expresie[i] == '|') {
                subExpresii[nSubExp++] = evalueazaAND(expresie, variabile, ultimaPozitie, i);

                ultimaPozitie = i + 1;
            }
    }

    subExpresii[nSubExp++] = evalueazaAND(expresie, variabile, ultimaPozitie, sfarsit);

    if(nSubExp == 1)
        return subExpresii[0];
    else for(int i = 0; i < nSubExp; i++)
        if(subExpresii[i])
            return true;

    return false;
}

bool evalueazaAND(char expresie[], bool variabile[], int start, int sfarsit) {
    int paranteze = 0, ultimaPozitie = start;

    bool subExpresii[1000];
    int nSubExp = 0;

    for(int i = ultimaPozitie; i < sfarsit; i++) {
        if(expresie[i] == '(')
            paranteze++;
        else if(expresie[i] == ')')
            paranteze--;

        if(paranteze == 0 && i <= sfarsit - 1)
            if(expresie[i] == '&') {
                subExpresii[nSubExp++] = evalueazaNOT(expresie, variabile, ultimaPozitie, i);

                ultimaPozitie = i + 1;
            }
    }

    subExpresii[nSubExp++] = evalueazaNOT(expresie, variabile, ultimaPozitie, sfarsit);

    if(nSubExp == 1)
        return subExpresii[0];

    bool raspuns = subExpresii[0];
    for(int i = 1; i < nSubExp; i++)
        raspuns = raspuns && subExpresii[i];

    return raspuns;
}

bool evalueazaNOT(char expresie[], bool variabile[], int start, int sfarsit) {
    if(expresie[start] == '!')
        return !evalueazaPAR(expresie, variabile, start + 1, sfarsit);

    return evalueazaPAR(expresie, variabile, start, sfarsit);
}

bool evalueazaPAR(char expresie[], bool variabile[], int start, int sfarsit) {
    if(expresie[start] == '(' && expresie[sfarsit - 1] == ')')
        return evalueazaExpresie(expresie, variabile, start + 1, sfarsit - 1);

    return evalueazaVAR(expresie, variabile, start, sfarsit);
}

bool evalueazaVAR(char expresie[], bool variabile[], int start, int sfarsit) {
    if(sfarsit - start > 1) {
        // should never happen
        return false;
    }

    if(expresie[start] == '0')
        return false;

    if(expresie[start] == '1')
        return true;

    if(expresie[start] >= 'A' && expresie[start] <= 'Z')
        return variabile[expresie[start] - 'A'];

    // should never happen
    return false;
}