Cod sursa(job #3237239)

Utilizator MihaiZ777MihaiZ MihaiZ777 Data 7 iulie 2024 12:34:54
Problema Bool Scor 80
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.23 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_OR,
    OT_AND,
    OT_NOT,
    OT_OPERAND,
    OT_UNDEFINED,
};

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

OperationType NextOperationType(OperationType op) {
    return (OperationType)(op + 1);
}

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

    if (lvl == OperationType::OT_OPERAND) {
        if (*p == '(') {
            p++;
            Expression(OperationType::OT_OR);
            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;
            p++;
        }   
    }
    else {
        for (x = Expression(NextOperationType(lvl)); CharToOperationType(*p) == lvl; x = y) {
            y = new Node(NodeType::NT_EXPRESSION, x, Expression(NextOperationType(lvl)), CharToOperationType(*p++));
        }
    }

    return x;
}

bool Evaluate(Node *node) {
    switch (node->type) {
        case NodeType::NT_VALUE:
            return node->value;
        case NodeType::NT_LETTER:
            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);
            }
    }
    cout << "Something went wrong.\n";
    return 0;
}

void WriteAnswer(Node *exprTree) {
    FILE *f = fopen("bool.out", "w");
    for (int i = 0; i < n; i++) {
        values[flippers[i] - 'A'] = !values[flippers[i] - 'A'];

        bool ans = Evaluate(exprTree);
        fprintf(f, "%d", ans);
    }
    fclose(f);
}

int main() {
    ReadInput();
    Simplify();
    Node *exprTree = Expression(OperationType::OT_OR);
    WriteAnswer(exprTree);

    return 0;
}