#include #include #include #include #include using namespace std; #define REGMAX 26 #define LPAR 100 #define RPAR 101 #define NOT 102 #define AND 103 #define OR 104 #define TRUE 105 #define FALSE 106 #define ENDTKN 107 bool evalExpr ( int &cursor, const vector &T ); bool evalTerm ( int &cursor, const vector &T ); bool evalFactor ( int &cursor, const vector &T ); bool getRegister( int regid ); vector tokenize( string &E ) { E += ' '; vector result; for ( int cursor = 0; cursor < E.size(); cursor++ ) { if ( isspace(E[cursor]) ) continue; switch ( E[cursor] ) { case '(': result.push_back(LPAR); break; case ')': result.push_back(RPAR); break; case 'N': if ( E[cursor+1] == 'O' && E[cursor+2] == 'T' ) result.push_back(NOT), cursor += 2; else result.push_back('N'-'A'); break; case 'A': if ( E[cursor+1] == 'N' && E[cursor+2] == 'D' ) result.push_back(AND), cursor += 2; else result.push_back('A'-'A'); break; case 'O': if ( E[cursor+1] == 'R' ) result.push_back(OR), cursor += 1; else result.push_back('R'-'A'); break; case 'T': if ( E[cursor+1] == 'R' && E[cursor+2] == 'U' && E[cursor+3] == 'E' ) result.push_back(TRUE), cursor += 3; else result.push_back('T'-'A'); break; case 'F': if ( E[cursor+1] == 'A' && E[cursor+2] == 'L' && E[cursor+3] == 'S' && E[cursor+4] == 'E' ) result.push_back(FALSE), cursor += 4; else result.push_back('F'-'A'); break; default: assert( isupper(E[cursor]) ); result.push_back(E[cursor]-'A'); } } result.push_back(ENDTKN); return result; } bool evalExpr( int &cursor, const vector &T ) { bool result = evalTerm(cursor, T); while ( T[cursor] == OR ) { cursor++; const bool right = evalTerm(cursor, T); result |= right; } return result; } bool evalTerm( int &cursor, const vector &T ) { bool result = evalFactor(cursor, T); while ( T[cursor] == AND ) { cursor++; const bool right = evalFactor(cursor, T); result &= right; } return result; } bool evalFactor( int &cursor, const vector &T ) { bool invert = false; while ( T[cursor] == NOT ) invert = !invert, cursor++; bool atom; switch ( T[cursor] ) { case LPAR: cursor++; atom = evalExpr(cursor, T); assert( T[cursor] == RPAR ); cursor++; break; case TRUE: cursor++; atom = true; break; case FALSE: cursor++; atom = false; break; default: assert( T[cursor] <= REGMAX ); atom = getRegister(T[cursor]); cursor++; } return atom^invert; } #define EMPTY 0 #define FORK 1 #define REGINV 2 #define GRIDSIZE 210 #define SHIFT 105 #define LEFT 0 #define UP 1 #define RIGHT 2 #define DOWN 3 string exprString; vector tokenized; int N, nfork, nreginv; bool REG[26]; int bufR[GRIDSIZE][GRIDSIZE]; int bufA[GRIDSIZE][GRIDSIZE]; int &A( int x, int y ) { return bufA[x+SHIFT][y+SHIFT]; } int &R( int x, int y ) { return bufR[x+SHIFT][y+SHIFT]; } bool getRegister( int regid ) { return REG[regid]; } bool eval() { int cursor = 0; const bool result = evalExpr(cursor, tokenized); return result; } bool dropped( int x, int y ) { const int ax = abs(x); const int ay = abs(y); return ( ax > N || ay > N ); } void simulate() { const int dx[] = {-1, 0, +1, 0}; const int dy[] = {0, +1, 0, -1}; int x = 0, y = 0; int direction = RIGHT; bool ev; while ( !dropped(x, y) ) { cout << x << " " << y << endl; x += dx[direction]; y += dy[direction]; switch ( A(x, y) ) { case EMPTY: break; case REGINV: REG[R(x, y)] = !REG[R(x, y)]; break; case FORK: ev = eval(); if ( ev ) direction = (direction+1) % 4; else direction = (direction+3)%4; break; default: assert( false ); } } } int main() { getline(cin, exprString); tokenized = tokenize(exprString); cin >> N >> nfork >> nreginv; for ( int x = -N; x <= N; x++ ) for ( int y = -N; y <= N; y++ ) A(x, y) = EMPTY; for ( int i = 0; i < 26; i++ ) REG[i] = false; int x, y; char regid; for ( int i = 0; i < nfork; i++ ) { cin >> x >> y; A(x, y) = FORK; } for ( int i = 0; i < nreginv; i++ ) { cin >> x >> y >> regid; A(x, y) = REGINV; R(x, y) = regid-'A'; } simulate(); return 0; }