Cod sursa(job #2481192)

Utilizator buhaidarius@gmail.comBuhai Darius [email protected] Data 26 octombrie 2019 16:30:01
Problema Bool Scor 10
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.89 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>

using namespace std;

int n;
int val[27], TRR, FAA;
bool lval[27];

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, int pow = 1){
    if(modif.size()==0) return;
    for(int i=1;i<=27;i++){
        if(char_to_int(modif[0])==i) lval[i] = !lval[i];
        if(lval[i]) val[i]+=pow;
    }
    memorize_constants(modif.substr(1), pow*2);
}

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

// 5 |
// 1 &
// 2 |
// 3

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

void add_all(vector<pair<int,char>> &con, vector<char> &op){
    reverse(op.begin(), op.end());
    while(!op.empty()){
        con.push_back({0, op.back()});
        op.pop_back();
    }
}

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

int walk_eval(string exp, vector<pair<int,char>> con = {}, vector<char> op = {}){
    if(exp[0]==' ') return walk_eval(exp.substr(1), con, op);
    if(exp.size()==0){
        add_all(con, op);
        //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"){
        bool found = false;
        for(auto cop : op) if(cop=='!') found = true;
        if(found) add_all(con, op);
        op.push_back('!');
        sort(op.begin(), op.end());
        return walk_eval(exp.substr(3), con, op);
    }
    if(exp.substr(0,3)=="AND"){
        bool found = false;
        for(auto cop : op) if(cop=='&' || cop=='!') found = true;
        if(found) add_all(con, op);
        op.push_back('&');
        sort(op.begin(), op.end());
        return walk_eval(exp.substr(3), con, op);
    }
    if(exp.substr(0,2)=="OR"){
        bool found = false;
        for(auto cop : op) if(cop=='|' || cop=='!') found = true;
        if(found) add_all(con, op);
        op.push_back('|');
        sort(op.begin(), op.end());
        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);
    
    FAA = 0;
    TRR = 0;
    for(int i=0, p = 1;i<n;i++, TRR+=p, p*=2);
    
    memorize_constants(modif);
    int rez = walk_eval(exp);
    
    for(int i=0;i<n;i++, rez/=2){
        if(rez%2==0) cout<<0;
        else cout<<1;
    }
    return 0;
}