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

#include <algorithm>
#include <cassert>
#include <cctype>
#include <cstdint>
#include <cstdio>
#include <string>
#include <vector>

bool next_operation(std::string &s) {
  for (size_t i = s.length(); i--;) {
    if (s[i] == 'A') {
      s[i] = 'O';
      return true;
    } else if (s[i] == 'O') {
      s[i] = 'X';
      return true;
    } else if (s[i] == 'X') {
      s[i] = 'A';
    }
  }
  return false;
}

int parse(const std::string &s, size_t &i, size_t preced = 0) {
  const std::vector<std::string> ops = {"AOX"};

  if (preced == ops.size()) {
    if (s[i] == '(') {
      int res = parse(s, ++i, 0);
      assert(s[i] == ')');
      ++i;
      return res;
    }
    if ('0' <= s[i] && s[i] < '0' + 16) {
      return s[i++] - '0';
    }
    assert(false);
  }

  int lhs = parse(s, i, preced + 1);
  while (i < s.length()) {
    char op = s[i];
    if (!isupper(op))
      break;
    int rhs = parse(s, ++i, preced + 1);
    if (op == 'A')
      lhs &= rhs;
    if (op == 'O')
      lhs |= rhs;
    if (op == 'X')
      lhs ^= rhs;
  }
  return lhs;
}

int testcase_ends() {
  char buf[1024];
  scanf(" %[^\\n]", buf);
  std::string s = buf;
  if (s == "END")
    return 1;

  size_t n;
  scanf("%zu", &n);
  std::vector<int> item(n);
  for (size_t i = 0; i < n; ++i) {
    for (int j = 0; j < 4; ++j) {
      int x;
      scanf("%d", &x);
      item[i] |= x << j;
    }
  }

  {
    for (size_t i = 0; i < s.length(); ++i) {
      if (isdigit(s[i])) {
        s[i] = item[s[i] - '1'] + '0';
      } else if (s[i] == ' ') {
        s[i] = 'A';
      }
    }
  }

  int res = 0;
  do {
    size_t i = 0;
    if (parse(s, i) == 15)
      ++res;
  } while (next_operation(s));
  printf("%d\\n", res);
  return 0;
}

int main() {
  while (!testcase_ends()) {
  }
}


Error: 0

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cctype>
#include <cstdint>
#include <cstdio>
#include <string>
#include <vector>

bool next_operation(std::string &s) {
  for (size_t i = s.length(); i--;) {
    if (s[i] == 'A') {
      s[i] = 'O';
      return true;
    } else if (s[i] == 'O') {
      s[i] = 'X';
      return true;
    } else if (s[i] == 'X') {
      s[i] = 'A';
    }
  }
  return false;
}

int parse(const std::string &s, size_t &i, size_t preced = 0) {
  const std::vector<std::string> ops = {"AOX"};

  if (preced == ops.size()) {
    if (s[i] == '(') {
      int res = parse(s, ++i, 0);
      assert(s[i] == ')');
      ++i;
      return res;
    }
    if ('0' <= s[i] && s[i] < '0' + 16) {
      return s[i++] - '0';
    }
    assert(false);
  }

  int lhs = parse(s, i, preced + 1);
  while (i < s.length()) {
    char op = s[i];
    if (!isupper(op))
      break;
    int rhs = parse(s, ++i, preced + 1);
    if (op == 'A')
      lhs &= rhs;
    if (op == 'O')
      lhs |= rhs;
    if (op == 'X')
      lhs ^= rhs;
  }
  return lhs;
}

int testcase_ends() {
  char buf[1024];
  scanf(" %[^\\n]", buf);
  std::string s = buf;
  if (s == "END")
    return 1;

  size_t n;
  scanf("%zu", &n);
  std::vector<int> item(n);
  for (size_t i = 0; i < n; ++i) {
    for (int j = 0; j < 4; ++j) {
      int x;
      scanf("%d", &x);
      item[i] |= x << j;
    }
  }

  {
    size_t ii = 0;
    for (size_t i = 0; i < s.length(); ++i) {
      if (isdigit(s[i])) {
        s[i] = item[ii++] + '0';
      } else if (s[i] == ' ') {
        s[i] = 'A';
      }
    }
  }

  int res = 0;
  do {
    size_t i = 0;
    if (parse(s, i) == 15)
      ++res;
  } while (next_operation(s));
  printf("%d\\n", res);
  return 0;
}

int main() {
  while (!testcase_ends()) {
  }
}