Problem p00736 (C++) — buggy submission, verdict: Runtime Error

#include <algorithm>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define EPS 1e-10
#define F first
#define S second
#define all(n) n.begin(), n.end()
#define pb push_back
#define insert(a, b, c, d) PP(P(a, b), P(c, d))
#define INF (1 << 27)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> P;
typedef pair<P, P> PP;
const int dx[4] = {0, 1, 0, -1};
const int dy[4] = {1, 0, -1, 0};

int mul(int X, int Y) {
  if (X == 0 || Y == 0)
    return 0;
  if (X == 1 || Y == 1)
    return 1;
  if (X == 2 && Y == 2)
    return Y;
  assert(false);
}

int add(int X, int Y) {
  if (X == 0)
    return Y;
  if (X == 1 && (Y == 0 || Y == 1))
    return 1;
  if (X == 1 && Y == 2)
    return 2;
  if (X == 2)
    return 2;
  assert(false);
}

int sub(int X) {
  // cout << "X = "<< X << endl;
  if (X == 0)
    return 2;
  if (X == 1)
    return 1;
  if (X == 2)
    return 0;
  assert(false);
}

class Parsing {
private:
  string parse;
  int pos;

public:
  Parsing(string s) {
    parse = s;
    pos = 0;
  }

  int fact() {
    if (parse[pos] == '(') {
      pos++;
      int p = expression();
      pos++;
      return p;
    } else if (parse[pos] == '-') {
      int p = 0;
      int cnt = 0;
      while (parse[pos] == '-') {
        cnt++, pos++;
      }
      // cout << "now parse = " << parse[pos] << endl;
      // p = parse[pos]-'0';
      // pos++;
      p = fact();
      // cout << "exp = " << p << endl;
      // pos++;
      rep(i, cnt) { p = sub(p); }
      // cout << " - IN!!! p = " << p << endl;
      return p;

    } else {

      int p = 0;

      while ('0' <= parse[pos] && parse[pos] <= '2') {
        p *= 10;
        p += parse[pos] - '0';
        pos++;
      }
      return p;
    }
  }

  int term() {
    int p = fact();
    return p;
  }

  int expression() {
    int p = term();
    // cout << "X = "<< p << endl;
    while (parse[pos] == '+' || parse[pos] == '*') {
      if (parse[pos] == '*') {
        pos++;
        int q = term();
        // cout << "Y = " <<q << endl;
        p = mul(p, q);
      } else if (parse[pos] == '+') {
        pos++;
        int q = term();
        // cout << "Y = "<< q << endl;
        p = add(p, q);
      }
    }
    return p;
  }
};

int ans, last;
string s;

void draw(char P, char Q, char R) {
  string pre = s;
  rep(i, s.length()) {
    if (s[i] == 'P')
      s[i] = P;
    else if (s[i] == 'Q')
      s[i] = Q;
    else if (s[i] == 'R')
      s[i] = R;
  }
  Parsing par = Parsing(s);
  int res = par.expression();
  assert(res == 0 || res == 1 || res == 2);
  if (res == 2)
    ans++;
  s = pre;
}

void test() {

  for (char i = '0'; i <= '2'; i++) {     // P
    for (char j = '0'; j <= '2'; j++) {   // Q
      for (char k = '0'; k <= '2'; k++) { // R
        draw(i, j, k);
      }
    }
  }
}

int main() {
  while (true) {
    cin >> s;
    // Parsing par = Parsing(s);
    // cout <<par.expression() << endl;
    // return 0;
    if (s == ".")
      break;
    ans = 0;
    test();
    cout << ans << endl;
  }
  return 0;
}

// ika gomi bako

Error: 0

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
#define EPS 1e-10
#define F first
#define S second
#define all(n) n.begin(), n.end()
#define pb push_back
#define insert(a, b, c, d) PP(P(a, b), P(c, d))
#define INF (1 << 27)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> P;
typedef pair<P, P> PP;
const int dx[4] = {0, 1, 0, -1};
const int dy[4] = {1, 0, -1, 0};

int mul(int X, int Y) {
  if (X == 0 || Y == 0)
    return 0;
  if (X == 1 || Y == 1)
    return 1;
  if (X == 2 && Y == 2)
    return Y;
  assert(false);
}

int add(int X, int Y) {
  if (X == 0)
    return Y;
  if (X == 1 && (Y == 0 || Y == 1))
    return 1;
  if (X == 1 && Y == 2)
    return 2;
  if (X == 2)
    return 2;
  assert(false);
}

int sub(int X) {
  if (X == 0)
    return 2;
  if (X == 1)
    return 1;
  if (X == 2)
    return 0;
  assert(false);
}

class Parsing {
private:
  string parse;
  int pos;

public:
  Parsing(string s) {
    parse = s;
    pos = 0;
  }

  int fact() {
    if (parse[pos] == '(') {
      pos++;
      int p = expression();
      pos++;
      return p;
    } else if (parse[pos] == '-') {
      int p = 0;
      int cnt = 0;
      while (parse[pos] == '-') {
        cnt++, pos++;
      }
      p = parse[pos] - '0';
      pos++;
      rep(i, cnt) { p = sub(p); }
      return p;

    } else {

      int p = 0;

      while ('0' <= parse[pos] && parse[pos] <= '2') {
        p *= 10;
        p += parse[pos] - '0';
        pos++;
      }
      return p;
    }
  }

  int term() {
    int p = fact();
    return p;
  }

  int expression() {
    int p = term();
    // cout << "X = "<< p << endl;
    while (parse[pos] == '+' || parse[pos] == '*') {
      if (parse[pos] == '*') {
        pos++;
        int q = term();
        // cout << "Y = " <<q << endl;
        p = mul(p, q);
      } else if (parse[pos] == '+') {
        pos++;
        int q = term();
        // cout << "Y = "<< q << endl;
        p = add(p, q);
      }
    }
    return p;
  }
};

int ans, last;
string s;

void draw(char P, char Q, char R) {
  string pre = s;
  rep(i, s.length()) {
    if (s[i] == 'P')
      s[i] = P;
    else if (s[i] == 'Q')
      s[i] = Q;
    else if (s[i] == 'R')
      s[i] = R;
  }
  Parsing par = Parsing(s);
  int res = par.expression();
  assert(res == 0 || res == 1 || res == 2);
  if (res == 2)
    ans++;
  s = pre;
}

void test() {

  for (char i = '0'; i <= '2'; i++) {     // P
    for (char j = '0'; j <= '2'; j++) {   // Q
      for (char k = '0'; k <= '2'; k++) { // R
        draw(i, j, k);
      }
    }
  }
}

int main() {
  while (true) {
    cin >> s;
    if (s == ".")
      break;
    ans = 0;
    test();
    cout << ans << endl;
  }
  return 0;
}