Cod sursa(job #1424970)

Utilizator tamionvTamio Vesa Nakajima tamionv Data 26 aprilie 2015 07:18:18
Problema Bool Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.31 kb
#include <fstream>
#include <iostream>
#include <vector>
#include <string>
#include <cstdlib>
#include <stack>
#include <unordered_map>
using namespace std;

void lex(const string& from, string& to, unordered_map<char, bool>& dict){
	auto it = begin(from);
	while(it != end(from)){
		if(*it == 'A' && *(it+1) == 'N'){
			to.push_back('&');
			it += 3; }
		else if(*it == 'O' && *(it+1) == 'R'){
			to.push_back('|');
			it += 2; }
		else if(*it == 'N' && *(it+1) == 'O'){
			to.push_back('!');
			it += 3; }
		else if(*it == 'T' && *(it+1) == 'R'){
			to.push_back('t');
			it += 4; }
		else if(*it == 'F' && *(it+1) == 'A'){
			to.push_back('f');
			it += 5; }
		else if(*it == '('){
			to.push_back('(');
			++it; }
		else if(*it == ')'){
			to.push_back(')');
			++it; }
		else{
			to.push_back(*it);
			dict[*it] = false;
			++it; }
		while(isspace(*it)){
			++it; } } }

constexpr int precedence(const char c){
	return (c == '(') ? -1 : (c == '|') ? 0 : (c == '&') ? 1 : (c == '!') ? 2 : 3; }

void parse(const string& from, string& to){
	stack<char> st;
	for(auto x : from){
		if(x == '('){
			st.push('('); }
		else if(x == ')'){
			while((!st.empty()) && st.top() != '('){
				to.push_back(st.top());
				st.pop(); }
			st.pop(); }
		else if(isalpha(x)){
			to.push_back(x); }
		else{
			const int prec = precedence(x);
			while((!st.empty()) && precedence(st.top()) > prec){
				to.push_back(st.top());
				st.pop(); }
			st.push(x); } }
	while(!st.empty()){
		to.push_back(st.top());
		st.pop(); } }

bool eval(string::iterator& loc, unordered_map<char, bool>& dict){
	static bool first;
	switch(*loc){
	case '!':
		--loc;
		return !eval(loc, dict);
	case '&':
		--loc;
		first = eval(loc, dict);
		return eval(loc, dict) && first;
	case '|':
		--loc;
		first = eval(loc, dict);
		return eval(loc, dict) || first;
	case 't':
		--loc;
		return true;
	case 'f':
		--loc;
		return false;
	default:
		return dict[*(loc--)]; } }

int main(){
	ifstream f("bool.in");
	ofstream g("bool.out");
	string brut, lexat, parsat;
	unordered_map<char, bool> dict;
	getline(f, brut);
	lex(brut, lexat, dict);
	parse(lexat, parsat);
	cout << brut << '\n' << lexat << '\n' << parsat << '\n';
	int n = 0;	
	f >> n >> ws;
	string s(n, 0);
	f.read(&s[0], n);
	for(int i = 0; i < n; ++i){
		dict[s[i]] = !dict[s[i]];
		auto it = end(parsat)-1;
		g << eval(it, dict); }
	return 0; }