Cod sursa(job #3237222)

Utilizator MihaiZ777MihaiZ MihaiZ777 Data 7 iulie 2024 11:45:16
Problema Bool Scor 70
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.37 kb
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;

const int MAX_N = 105;
const int MAX_LEN = 1005;

enum NodeType {
    NT_DEFAULT,
    NT_VALUE,
    NT_LETTER,
    NT_EXPRESSION,
};

enum OperationType {
    OT_NOT,
    OT_AND,
    OT_OR,
    OT_MAX,
    OT_UNDEFINED,
};

OperationType opPrio[3] = {OperationType::OT_NOT, OperationType::OT_AND, OperationType::OT_OR};

struct Node {
    NodeType type;
    Node *lf;
    Node *rg;
    OperationType op;
    char letter;
    bool value;

    Node(NodeType t = NodeType::NT_DEFAULT, Node *l = 0, Node *r = 0,
            OperationType o = (OperationType)0) {
        type = t;
        lf = l;
        rg = r;
        op = o;
    }
};

char expr[MAX_LEN];
char *p = expr;
int n;
char flippers[MAX_N];
bool values[30];

void ReadInput() {
    FILE *f = fopen("bool.in", "r");
    fgets(expr, MAX_LEN, f);
    fscanf(f, "%d", &n);
    fscanf(f, "%s\n", flippers);
    fclose(f);
}

void Simplify() {
    char* writePtr = expr;
    char* readPtr = expr;

    while (*readPtr != '\n' && *readPtr != '\0') {
        if (*readPtr == '(' || *readPtr == ')') {
            *writePtr++ = *readPtr++;
        }
        else if (strstr(readPtr, "TRUE") == readPtr) {
            *writePtr++ = '1';
            readPtr += 4;
        }
        else if (strstr(readPtr, "FALSE") == readPtr) {
            *writePtr++ = '0';
            readPtr += 5;
        }
        else if (strstr(readPtr, "NOT") == readPtr) {
            *writePtr++ = '!';
            readPtr += 3;
        }
        else if (strstr(readPtr, "AND") == readPtr) {
            *writePtr++ = '&';
            readPtr += 3;
        }  
        else if (strstr(readPtr, "OR") == readPtr) {
            *writePtr++ = '|';
            readPtr += 2;
        }
        else if (*readPtr != ' ') {
            *writePtr++ = *readPtr++;
        }
        else {
            readPtr++;
        }
    }
    *writePtr = '\0';
}

OperationType CharToOperationType(char c) {
    switch (c) {
        case '!':
            return OperationType::OT_NOT;
        case '&':
            return OperationType::OT_AND;
        case '|':
            return OperationType::OT_OR;
        default:
            return OperationType::OT_UNDEFINED;
    }
}

Node *Expression(OperationType lvl) {
    Node *x, *y;

    if (lvl == OperationType::OT_MAX) {
        if (*p == '(') {
            p++;
            Expression((OperationType)0);
            p++;
        }
        else if (*p == '0' || *p == '1') {
            x = new Node();
            x->value = *p - '0';
            x->type = NodeType::NT_VALUE;
            p++;
        }
        else if ('A' <= *p && *p <= 'Z'){
            x = new Node();
            x->letter = *p;
            x->type = NodeType::NT_LETTER;
            // cout << x->letter << ' ';
            p++;
        }   
    }
    else {
        for (x = Expression((OperationType)(lvl + 1)); CharToOperationType(*p) == lvl; x = y) {
            y = new Node(NodeType::NT_EXPRESSION, x, Expression((OperationType)(lvl + 1)), CharToOperationType(*p));
            p++;
        }
    }

    return x;
}

bool Evaluate(Node *node) {
    switch (node->type) {
        case NodeType::NT_VALUE:
            return node->value;

        case NodeType::NT_LETTER:
            // cout << "LETTER: " << node->letter << ' ' << values[node->letter - 'A'];
            return values[node->letter - 'A'];
            
        case NodeType::NT_EXPRESSION:
            switch (node->op) {
                case OperationType::OT_NOT:
                    return !node->value;

                case OperationType::OT_AND:
                    return Evaluate(node->lf) & Evaluate(node->rg);

                case OperationType::OT_OR:
                    return Evaluate(node->lf) | Evaluate(node->rg);
            }
    }
}

int main() {
    ReadInput();
    Simplify();
    Node *exprTree = Expression((OperationType)0);

    FILE *f = fopen("bool.out", "w");
    for (int i = 0; i < n; i++) {
        values[flippers[i] - 'A'] = !values[flippers[i] - 'A'];
        for (int j = 0; j < 26; j++) {
            // cout << values[j];
        }
        // cout <<'\n';
        bool ans = Evaluate(exprTree);

        
        fprintf(f, "%d", ans);
        
    }
    fclose(f);
}