Cod sursa(job #638982)

Utilizator calinuxIorgulescu Calin calinux Data 22 noiembrie 2011 03:34:21
Problema Bool Scor 30
Compilator c Status done
Runda Arhiva de probleme Marime 3.73 kb
#include <stdio.h>
#include <string.h>

#define FALSE 0
#define TRUE 1
#define NOT 2
#define AND 3
#define OR 4
#define CHAR_TO_INT(x) ((x - 'A') + 5)
#define INT_TO_IDX(x) (x - 5)
//#define PARANTHESIS -1
#define PARANTHESIS 100

#define MaxL 1000
#define MaxN 100
#define NLetters 24

char str_expr[MaxL + 1];
int expr[MaxL + 1], expr_fin;
int values[NLetters + 1];
int change[MaxN + 1], n;
int st[MaxL + 1], st_idx;

void pretty_print(int i) {

	if (i == PARANTHESIS) {
		fprintf(stderr, ")");
		return;
	}

	if (i == FALSE) {
		fprintf(stderr, "0");
		return;
	}

	if (i == TRUE) {
		fprintf(stderr, "1");
		return;
	}

	if (i == NOT) {
		fprintf(stderr, "NOT");
		return;
	}

	if (i == AND) {
		fprintf(stderr, "AND");
		return;
	}

	if (i == OR) {
		fprintf(stderr, "OR");
		return;
	}

	fprintf(stderr, "%c", INT_TO_IDX(i) + 'A');

}


void gen_expr(void) {

	unsigned int str_st;

	for(str_st = 0 ; str_st < strlen(str_expr) ; str_st++) {

		if (str_expr[str_st] == ' ') continue;

		while (0) {
			int l;
			fprintf(stderr, "%s\n", str_expr + str_st);

			fprintf(stderr, "Expr: ");
			for (l = 0 ; l < expr_fin ; l++) {
				pretty_print(expr[l]);
				fprintf(stderr, " ");
			}

			fprintf(stderr, "\n");
			fprintf(stderr, "Stack: ");
			for (l = 0 ; l < st_idx ; l++) {
				pretty_print(st[l]);
				fprintf(stderr, " ");
			}
			fprintf(stderr, "\n");
			fprintf(stderr, "\n");

		}

		if (!strncmp(str_expr + str_st, "TRUE", 4)) {
			expr[expr_fin++] = TRUE;
			str_st += 3;
			continue;
		}

		if (!strncmp(str_expr + str_st, "FALSE", 5)) {
			expr[expr_fin++] = FALSE;
			str_st += 4;
			continue;
		}

		if (!strncmp(str_expr + str_st, "NOT", 3)) {

			if (st_idx)
				while (st[st_idx - 1] < NOT) {
					expr[expr_fin++] = st[--st_idx];
					if (!st_idx)
						break;
				}

			st[st_idx++] = NOT;
			str_st += 2;
			continue;
		}

		if (!strncmp(str_expr + str_st, "AND", 3)) {
			if (st_idx)
				while (st[st_idx - 1] < AND) {
					expr[expr_fin++] = st[--st_idx];
					if (!st_idx)
						break;
				}

			st[st_idx++] = AND;
			str_st += 2;
			continue;
		}

		if (!strncmp(str_expr + str_st, "OR", 2)) {
			if (st_idx)
				while (st[st_idx - 1] < OR) {
					expr[expr_fin++] = st[--st_idx];
					if (!st_idx)
						break;
				}

			st[st_idx++] = OR;
			str_st += 1;
			continue;
		}

		if (str_expr[str_st] == '(') {
			st[st_idx++] = PARANTHESIS;
			continue;
		}

		if (str_expr[str_st] == ')') {

			st_idx--;
			while (st[st_idx] != PARANTHESIS)
				expr[expr_fin++] = st[st_idx--];

			continue;
		}

		expr[expr_fin++] = CHAR_TO_INT(str_expr[str_st]);

	}

	while (st_idx)
		expr[expr_fin++] = st[--st_idx];

}

int eval_expr(void) {

	int i;
	st_idx = 0;

	for (i = 0 ; i < expr_fin ; i++) {

		while(0) {
			int j;
			for(j = 0 ; j < st_idx ; j++)
				fprintf(stderr, "%d ", st[j]);

			fprintf(stderr, "\n");
		}
		if (expr[i] < 2 || expr[i] > 4) {
			st[st_idx++] = values[INT_TO_IDX(expr[i])];
			continue;
		}

		if (expr[i] == 2) {
			st[st_idx - 1] ^= 1;
			continue;
		}

		if (expr[i] == 3) {
			int a, b;

			a = st[--st_idx];
			b = st[--st_idx];

			st[st_idx++] = a & b;
			continue;
		}

		if (expr[i] == 4) {
			int a, b;

			a = st[--st_idx];
			b = st[--st_idx];

			st[st_idx++] = a | b;
			continue;
		}
	}

	// fprintf(stderr, "***\n");

	return st[st_idx - 1];

}

void read(void) {

	int i = 0;
	char c;
	freopen("bool.in", "r", stdin);

	do {
		scanf("%c", &c);
		if (c != '\n')
			str_expr[i++] = c;
	} while(c != '\n');

	str_expr[i] = '\0';

	scanf("%d\n", &n);

	for (i = 0 ; i < n ; i++) {
		scanf("%c", &c);
		change[i] = c - 'A';
	}

}

void solve(void) {

	int i;

	gen_expr();

	freopen("bool.out", "w", stdout);

	for (i = 0 ; i < n ; i++) {
		values[change[i]] ^= 1;
		printf("%d", eval_expr());
	}

}

int main(void) {

	read();
	solve();

	return 0;

}