Cod sursa(job #139032)

Utilizator scvalexAlexandru Scvortov scvalex Data 19 februarie 2008 17:34:07
Problema Bool Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.69 kb
#include <iostream>
#include <fstream>
#include <cstring>
#include <stack>

using namespace std;

typedef unsigned int uint;

const int priority[6] = {
	-666,
	3,
	1,
	2,
	-4,
	-5
};

enum Token {
	NOT = -1,
	OR = -2,
	AND = -3,
	OB = -4,
	CB = -5,
	TRUE = 30,
	FALSE = 31
};

char exp[11024];
int tl[11024];
bool vars[32];
int pos;

bool boolExpression();

bool factor() {
	bool a;

	if (tl[pos] > 0) {
		a = vars[tl[pos]];
		++pos;
	} else if (NOT == tl[pos]) {
		++pos;
		a = !factor();
	} else if (OB == tl[pos]) {
		++pos;
		a = boolExpression();
		++pos;
	}

	return a;
}

bool boolTerm() {
//	cout << "{BT(" << pos << ") ";
	bool a = factor();
	while (AND == tl[pos]) {
		++pos;
		bool b = factor();
		a = a && b;
	}
//	cout << "BT(" << pos << ")}";
	return a;
}

bool boolExpression() {
//	cout << "{BE(" << pos << ") ";
	bool a = boolTerm();
	while (OR == tl[pos]) {
		++pos;
		bool b = boolTerm();
		a = a || b;
	}
//	cout << "BE(" << pos << ")}";
	return a;
}

bool evalBool(stack<int> &outputStack) {
	if (outputStack.empty())
		cout << "Crap" << endl;

	int top = outputStack.top();
	outputStack.pop();

	if (top >= 0)
		return top;

	bool a = evalBool(outputStack);
	if (top == NOT)
		return !a;

	bool b = evalBool(outputStack);
	if (top == AND)
		return a && b;

	return a || b;
}

bool parseExpression() {
	stack<int> outputStack;
	stack<int> operatorStack;

	int vah(0);
	for (int i(0); tl[i] != -888; ++i, ++vah) {
		if (tl[i] > 0)
			outputStack.push(vars[tl[i]]);
		else if ((tl[i] == OR) || (tl[i] == NOT) || (tl[i] == AND)) {
			int curP = priority[-tl[i]];
			while (!operatorStack.empty() && (priority[-operatorStack.top()] >= curP)) {
				outputStack.push(operatorStack.top());
				operatorStack.pop();
			}
			operatorStack.push(tl[i]);
		} else if (tl[i] == OB)
			operatorStack.push(OB);
		else if (tl[i] == CB) {
			while (!operatorStack.empty() && (operatorStack.top() != OB)) {
				outputStack.push(operatorStack.top());
				operatorStack.pop();
			}
			operatorStack.pop();
		} else
			cout << "Ignored: " << tl[i] << endl;
	}

	while (!operatorStack.empty()) {
		outputStack.push(operatorStack.top());
		operatorStack.pop();
	}

	/*cout << vah << " " << outputStack.size() << endl;
	while (!outputStack.empty()) {
		cout << outputStack.top() << " ";
		outputStack.pop();
	}
	cout << endl;*/

	bool result = evalBool(outputStack);

	return result;
}

int main(int argc, char *argv[]) {
	ifstream fin("bool.in");	
	fin.getline(exp, 11024);

	pos = 0;
	for (uint i (0); i < strlen(exp); ++i) {
		if (exp[i] == ' ')
			continue;

		switch (exp[i]) {
			case 'T':
				if ('R' == exp[i+1]) {
					tl[pos++] = TRUE;
					i += 4;
				} else goto letter;
				break;
			case 'F':
				if ('A' == exp[i+1]) {
					tl[pos++] = FALSE;
					i += 4;
				} else goto letter;
				break;
			case 'N':
				if ('O' == exp[i+1]) {
					tl[pos++] = NOT;
					i += 2;
				} else goto letter;
				break;
			case 'O':
				if ('R' == exp[i+1]) {
					tl[pos++] = OR;
					i += 1;
				} else goto letter;
				break;
			case 'A':
				if ('N' == exp[i+1]) {
					tl[pos++] = AND;
					i += 2;
				} else goto letter;
				break;
			case '(':
				tl[pos++] = OB;
				break;
			case ')':
				tl[pos++] = CB;
				break;
			default:
letter:
				tl[pos++] = exp[i] - 'A' + 1;
		}
	}
	tl[pos] = -888;

	/*for (int i(0); tl[i] != -888; ++i)
		cout << tl[i] << " ";
	cout << endl;*/

	for (int i(0); i < 32; ++i)
		vars[i] = false;
	vars[TRUE] = true;

	int N;
	fin >> N;
	char c;
	ofstream fout("bool.out");
	while (N--) {
		fin >> c;
		vars[c - 'A' + 1] = !vars[c - 'A' + 1];
		pos = 0;
//		for (int i(0); i < 26; ++i)
//			cout << vars[i];
//		cout << endl;
		//fout << boolExpression();
		fout << parseExpression();
	}
	fout << endl;
	fout.close();
	fin.close();

	return 0;
}