Cod sursa(job #2482830)

Utilizator buhaidarius@gmail.comBuhai Darius [email protected] Data 28 octombrie 2019 21:49:21
Problema Bool Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.85 kb
//
//  main.cpp
//  Bool
//
//  Created by Darius Buhai on 25/10/2019.
//  Copyright © 2019 Darius Buhai. All rights reserved.
//

#include <iostream>
#include <cstdio>
#include <vector>
#include <string>
#include <algorithm>
#include <deque>

using namespace std;

int n;

vector<bool> val[30], TRR, FAA;
bool lval[30];

bool is_letter(char c){
    if(c>='A' && c<='Z')
        return true;
    return false;
}

int char_to_int(char c){
    return (int)(c-'A'+1);
}

void memorize_constants(string modif){
    if(modif.size()==0) return;
    for(int i=1;i<=27;i++){
        if(char_to_int(modif[0])==i) lval[i] = !lval[i];
        val[i].push_back(lval[i]);
    }
    memorize_constants(modif.substr(1));
}

int next_phar(string exp){
    int lvl = 1;
    for(int i=0;i<exp.size();i++){
        if(exp[i]==')') lvl--;
        if(exp[i]=='(') lvl++;
        if(lvl==0) return i;
    }
    return -1;
}

vector<bool> eval(vector<pair<vector<bool>,char>> &con){
    int i = con.size()-1;
    vector<bool> a, b;
    if(con[i].second=='!'){
        con.pop_back();
        a = eval(con);
        for(int i=0;i<n;i++) a[i] = !a[i];
        return a;
    }
    if(con[i].second=='&'){
        con.pop_back();
        a = eval(con);
        b = eval(con);
        for(int i=0;i<n;i++) a[i] = a[i]&&b[i];
        return a;
    }
    if(con[i].second=='|'){
        con.pop_back();
        a = eval(con);
        b = eval(con);
        for(int i=0;i<n;i++) a[i] = a[i]||b[i];
        return a;
    }
    a = con[i].first;
    con.pop_back();
    return a;
}

void show_con(vector<pair<vector<bool>,char>> con){
    for(auto cop : con){
        if(cop.first.size()>0) cout<<"X ";
        if(cop.second!=0) cout<<cop.second<<" ";
    }
}

vector<bool> walk_eval(string exp, vector<pair<vector<bool>,char>> con = {}, deque<char> op = {}){
    if(exp[0]==' ') return walk_eval(exp.substr(1), con, op);
    if(exp.size()==0){
        while(!op.empty()){
            con.push_back({{}, op.back()});
            op.pop_back();
        }
        //show_con(con);
        return eval(con);
    }
    // Constants
    if(is_letter(exp[0]) && !is_letter(exp[1])){
        con.push_back({val[char_to_int(exp[0])], 0});
        return walk_eval(exp.substr(1), con, op);
    }
    if(exp.substr(0,4)=="TRUE"){
        con.push_back({TRR,0});
        return walk_eval(exp.substr(4), con, op);
    }
    if(exp.substr(0,4)=="FALSE"){
        con.push_back({FAA,0});
        return walk_eval(exp.substr(4), con, op);
    }
    // ()
    if(exp[0]=='('){
        exp = exp.substr(1);
        int np = next_phar(exp);
        con.push_back({walk_eval(exp.substr(0, np), {}, {}), 0});
        return walk_eval(exp.substr(np), con, op);
    }
    // Operators
    if(exp.substr(0,3)=="NOT"){
        /*while(!op.empty() && op.back()=='!'){
            con.push_back({{}, op.back()});
            op.pop_back();
        }*/
        op.push_back('!');
        return walk_eval(exp.substr(3), con, op);
    }
    if(exp.substr(0,3)=="AND"){
        while(!op.empty() && (op.back()=='!' || op.back()=='&')){
            con.push_back({{}, op.back()});
            op.pop_back();
        }
        op.push_back('&');
        return walk_eval(exp.substr(3), con, op);
    }
    if(exp.substr(0,2)=="OR"){
        while(!op.empty()){
            con.push_back({{}, op.back()});
            op.pop_back();
        }
        op.push_back('|');
        return walk_eval(exp.substr(3), con, op);
    }
    return walk_eval(exp.substr(1), con, op);
}

int main() {
    string exp, modif;
    
    freopen("bool.in", "r", stdin);
    freopen("bool.out", "w", stdout);
    
    getline(cin, exp);
    scanf("\n%d\n", &n);
    getline(cin, modif);
    
    for(int i=0;i<n;i++){
        TRR.push_back(1);
        FAA.push_back(0);
    }
    
    memorize_constants(modif);
    vector<bool> rez = walk_eval(exp);
    
    for(int i=0;i<n;i++)
        cout<<(int)rez[i];
    
    return 0;
}