Problem p01542 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <bitset>
#include <cctype>
#include <complex>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <limits.h>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <string>
#include <vector>

#define VARIABLE(x) cerr << #x << "=" << x << endl
#define BINARY(x) static_cast<bitset<16>>(x);
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define REP(i, m, n) for (int i = m; i < (int)(n); i++)
#define if_range(x, y, w, h)                                                   \
  if (0 <= (int)(x) && (int)(x) < (int)(w) && 0 <= (int)(y) &&                 \
      (int)(y) < (int)(h))

const int INF = 1000000000;
const double EPS = 1e-8;
const double PI = 3.14159;
int dx[4] = {0, 1, 0, -1}, dy[4] = {-1, 0, 1, 0};
using namespace std;
// typedef pair<int, int> P;
struct P {
  int x, y;
  P(int x, int y) : x(x), y(y) {}
  P() {}
};

/** Prbolem2428 : Lost Number **/
int p;
int N;
string c = "01+-*()";
string S;

int number(string s), expression(string s), factor(string s), term(string s);

bool err;

void valid(int n) {
  if (n < 0 || 1023 < n)
    err = true;
}

int factor(string s) {
  if (s[p] == '(') {
    p++;

    if (s[p] == '+' || s[p] == '-' || s[p] == '*' || s[p] == ')')
      err = true;
    int res = expression(s);
    if (s[p] != ')')
      err = true;

    p++;

    valid(res);
    return res;
  } else if (s[p] == ')') {
    err = true;
    return -1;
  } else if (isdigit(s[p])) {
    return number(s);
  } else {
    err = true;
  }
}

int term(string s) {
  int ret = factor(s);

  while (s[p] == '*') {
    p++;
    ret *= factor(s);
    valid(ret);
  }

  valid(ret);
  return ret;
}

int expression(string s) {
  int res = term(s);

  for (;;) {
    if (s[p] == '+') {
      p++;
      res += term(s);
    } else if (s[p] == '-') {
      p++;
      res -= term(s);
    } else {
      break;
    }
    valid(res);
  }

  valid(res);
  return res;
}

int number(string s) {
  int res = 0;

  while (isdigit(s[p])) {
    res *= 2;
    res += s[p++] - '0';
  }

  valid(res);
  return res;
}

bool isOpe(char c) { return (c == '+' || c == '-' || c == '*'); }

bool check(string s) {
  vector<int> ope;

  if (s[N - 1] == '+' || s[N - 1] == '-' || s[N - 1] == '*' || s[N - 1] == '(')
    return false;

  rep(i, s.size() - 1) {
    if (isOpe(s[i]) && isOpe(s[i + 1]))
      return false;
  }

  int d = -1;
  rep(i, s.size()) {
    if (s[i] == '(') {
      d++;
      if (i == s.size() - 1 || s[i + 1] == '+' || s[i + 1] == '-' ||
          s[i + 1] == '*' || s[i + 1] == ')')
        return false;
      if (i != 0 && !isOpe(s[i - 1]) && s[i - 1] != '(')
        return false;
      ope.push_back(0);
    } else if (s[i] == ')') {
      if (d < 0 || !ope[d])
        return false;
      ope.erase(ope.begin() + d);
      d--;
    } else if (s[i] == '+' || s[i] == '-' || s[i] == '*') {
      if (d >= 0)
        ope[d] = 1;
    }
  }

  if (d != -1)
    return false;
  return ope.end() == find(ope.begin(), ope.end(), 0);
}

int solve(int n, string s) {
  if (n == N) {
    p = 0;
    err = false;
    if (!check(s))
      err = 1;

    int res = expression(s);
    if (res >= 1024)
      res = -1;

    cerr << "Persing : " << s << endl;
    cerr << "    res : " << (err ? -1 : res) << endl;

    return err ? -1 : res;
  }

  int res = -1;
  if (S[n] != '.')
    res = solve(n + 1, s + S[n]);
  else
    rep(i, 7) {
      // if (n==N-1 && i>1) continue;
      res = max(res, solve(n + 1, s + c[i]));
    }

  return res;
}

int main() {
  cin >> S;
  N = (int)S.size();
  int res = solve(0, "");
  cout << max(-1, res) << endl;
}

Fixed submission:
#include <algorithm>
#include <bitset>
#include <cctype>
#include <complex>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <limits.h>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdio.h>
#include <string>
#include <vector>

#define VARIABLE(x) cerr << #x << "=" << x << endl
#define BINARY(x) static_cast<bitset<16>>(x);
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define REP(i, m, n) for (int i = m; i < (int)(n); i++)
#define if_range(x, y, w, h)                                                   \
  if (0 <= (int)(x) && (int)(x) < (int)(w) && 0 <= (int)(y) &&                 \
      (int)(y) < (int)(h))

const int INF = 1000000000;
const double EPS = 1e-8;
const double PI = 3.14159;
int dx[4] = {0, 1, 0, -1}, dy[4] = {-1, 0, 1, 0};
using namespace std;
// typedef pair<int, int> P;
struct P {
  int x, y;
  P(int x, int y) : x(x), y(y) {}
  P() {}
};

/** Prbolem2428 : Lost Number **/
int p;
int N;
string c = "01+-*()";
string S;

int number(string s), expression(string s), factor(string s), term(string s);

bool err;

void valid(int n) {
  if (n < 0 || 1023 < n)
    err = true;
}

int factor(string s) {
  if (s[p] == '(') {
    p++;

    if (s[p] == '+' || s[p] == '-' || s[p] == '*' || s[p] == ')')
      err = true;
    int res = expression(s);
    if (s[p] != ')')
      err = true;

    p++;

    valid(res);
    return res;
  } else if (s[p] == ')') {
    err = true;
    return -1;
  } else if (isdigit(s[p])) {
    return number(s);
  } else {
    err = true;
  }
}

int term(string s) {
  int ret = factor(s);

  while (s[p] == '*') {
    p++;
    ret *= factor(s);
    valid(ret);
  }

  valid(ret);
  return ret;
}

int expression(string s) {
  int res = term(s);

  for (;;) {
    if (s[p] == '+') {
      p++;
      res += term(s);
    } else if (s[p] == '-') {
      p++;
      res -= term(s);
    } else {
      break;
    }
    valid(res);
  }

  valid(res);
  return res;
}

int number(string s) {
  int res = 0;

  while (isdigit(s[p])) {
    res *= 2;
    res += s[p++] - '0';
  }

  valid(res);
  return res;
}

bool isOpe(char c) { return (c == '+' || c == '-' || c == '*'); }

bool check(string s) {
  vector<int> ope;

  if (s[N - 1] == '+' || s[N - 1] == '-' || s[N - 1] == '*' || s[N - 1] == '(')
    return false;

  rep(i, s.size() - 1) {
    if (isOpe(s[i]) && isOpe(s[i + 1]))
      return false;
  }

  int d = -1;
  rep(i, s.size()) {
    if (s[i] == '(') {
      d++;
      if (i == s.size() - 1 || s[i + 1] == '+' || s[i + 1] == '-' ||
          s[i + 1] == '*' || s[i + 1] == ')')
        return false;
      if (i != 0 && !isOpe(s[i - 1]) && s[i - 1] != '(')
        return false;
      ope.push_back(0);
    } else if (s[i] == ')') {
      if (d < 0 || !ope[d])
        return false;
      ope.erase(ope.begin() + d);
      d--;
    } else if (s[i] == '+' || s[i] == '-' || s[i] == '*') {
      if (d >= 0)
        ope[d] = 1;
    }
  }

  if (d != -1)
    return false;
  return ope.end() == find(ope.begin(), ope.end(), 0);
}

int solve(int n, string s) {
  if (n == N) {
    p = 0;
    err = false;
    if (!check(s))
      err = 1;

    int res = expression(s);
    if (res >= 1024)
      res = -1;

    // cerr << "Persing : " << s << endl;
    // cerr << "    res : " << (err?-1:res) << endl;

    return err ? -1 : res;
  }

  int res = -1;
  if (S[n] != '.')
    res = solve(n + 1, s + S[n]);
  else
    rep(i, 7) {
      // if (n==N-1 && i>1) continue;
      res = max(res, solve(n + 1, s + c[i]));
    }

  return res;
}

int main() {
  cin >> S;
  N = (int)S.size();
  int res = solve(0, "");
  cout << max(-1, res) << endl;
}