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

#include <bits/stdc++.h>
#define show(x) cerr << #x << " = " << (x) << endl
using namespace std;
using ll = long long;
class SyntaxAnalysis {
public:
  using T = pair<bool, int>;
  SyntaxAnalysis(const string &S) : S{S} {}
  T Expression() { return pos = 0, expression(); }

private:
  static constexpr char PLUS = '+';
  static constexpr char MINUS = '-';
  static constexpr char PRODUCT = '*';
  static constexpr char DIVIDE = '/';
  static constexpr char BRACE = '(';
  static T plus(const T &n, const T &k) {
    return {n.first and k.first and prop(n.second + k.second),
            n.second + k.second};
  }
  static T minus(const T &n, const T &k) {
    return {n.first and k.first and prop(n.second - k.second),
            n.second - k.second};
  }
  static T product(const T &n, const T &k) {
    return {n.first and k.first and prop(n.second * k.second),
            n.second * k.second};
  }
  static T divide(const T &n, const T &k) { return n; }
  static T brace(const T &n) { return n; }
  static bool is_digit(const char c) { return '0' <= c and c <= '1'; }
  static int encode(const char c) { return c - '0'; }
  static bool prop(const int l) { return l >= 0 and l < (1 << 10); }
  T number() {
    int ans = 0, start = S.size();
    for (; pos < S.size() and is_digit(S[pos]); pos++) {
      if (S[pos] == '1') {
        start = min(start, pos);
      }
      ans = ans * 2 + encode(S[pos]);
    }
    return {pos - start <= 10, ans};
  }
  T factor() {
    if (S[pos] == BRACE) {
      T ans;
      return pos++, ans = brace(expression()), pos++, ans;
    } else {
      return number();
    }
  }
  T term() {
    T ans = factor();
    for (T f; pos < S.size();) {
      if (S[pos] == PRODUCT) {
        pos++, f = factor(), ans = product(ans, f);
      } else if (S[pos] == DIVIDE) {
        pos++, f = factor(), ans = divide(ans, f);
      } else {
        break;
      }
    }
    return ans;
  }
  T expression() {
    T ans = term();
    for (T f; pos < S.size();) {
      if (S[pos] == PLUS) {
        pos++, f = term(), ans = plus(ans, f);
      } else if (S[pos] == MINUS) {
        pos++, f = term(), ans = minus(ans, f);
      } else {
        break;
      }
    }
    return ans;
  }
  int pos = 0;
  string S;
};
template <typename S, typename T>
inline ostream &operator<<(ostream &os, const pair<S, T> &p) {
  return (os << "<" << p.first << "," << p.second << ">");
}

int main() {
  constexpr char C[7] = {'0', '1', '+', '-', '*', '(', ')'};
  string s;
  cin >> s;
  vector<int> p;
  int NUM = 1;
  for (int i = 0; i < s.size(); i++) {
    if (s[i] == '.') {
      p.push_back(i), NUM *= 7;
    }
  }
  const int sz = p.size();
  int ans = -1;
  for (int i = 0; i < NUM; i++) {
    for (int j = 0, num = i; j < sz; j++, num /= 7) {
      s[p[j]] = C[num % 7];
    }
    stack<int> st;
    st.push(0);
    bool ok = true, num = false;
    for (const char c : s) {
      if (c == '(') {
        if (num) {
          ok = false;
          break;
        }
        st.push(0);
      } else if (c == ')') {
        if (st.size() <= 1 or st.top() == 0 or not num) {
          ok = false;
          break;
        }
        num = true;
        st.pop();
      } else if (c == '+' or c == '-' or c == '*') {
        if (not num) {
          ok = false;
          break;
        }
        num = false;
        const int n = st.top() + 1;
        st.pop(), st.push(n);
      } else {
        num = true;
      }
    }
    if (not ok or st.size() != 1 or not num) {
      continue;
    }
    const auto sub = SyntaxAnalysis{s}.Expression();
    // show(s);
    // show(sub);
    if (sub.first) {
      ans = max(ans, sub.second);
    }
  }
  cout << ans << endl;

  return 0;
}


Error: 0

Fixed submission:

#include <bits/stdc++.h>
#define show(x) cerr << #x << " = " << (x) << endl
using namespace std;
using ll = long long;
class SyntaxAnalysis {
public:
  using T = pair<bool, int>;
  SyntaxAnalysis(const string &S) : S{S} {}
  T Expression() { return pos = 0, expression(); }

private:
  static constexpr char PLUS = '+';
  static constexpr char MINUS = '-';
  static constexpr char PRODUCT = '*';
  static constexpr char DIVIDE = '/';
  static constexpr char BRACE = '(';
  static T plus(const T &n, const T &k) {
    return {n.first and k.first and prop(n.second + k.second),
            n.second + k.second};
  }
  static T minus(const T &n, const T &k) {
    return {n.first and k.first and prop(n.second - k.second),
            n.second - k.second};
  }
  static T product(const T &n, const T &k) {
    return {n.first and k.first and prop(n.second * k.second),
            n.second * k.second};
  }
  static T divide(const T &n, const T &k) { return n; }
  static T brace(const T &n) { return n; }
  static bool is_digit(const char c) { return '0' <= c and c <= '1'; }
  static int encode(const char c) { return c - '0'; }
  static bool prop(const int l) { return l >= 0 and l < 1 << 10; }
  T number() {
    int ans = 0, start = S.size();
    for (; pos < S.size() and is_digit(S[pos]); pos++) {
      if (S[pos] == '1') {
        start = min(start, pos);
      }
      ans = ans * 2 + encode(S[pos]);
    }
    return {pos - start <= 10, ans};
  }
  T factor() {
    if (S[pos] == BRACE) {
      T ans;
      return pos++, ans = brace(expression()), pos++, ans;
    } else {
      return number();
    }
  }
  T term() {
    T ans = factor();
    for (T f; pos < S.size();) {
      if (S[pos] == PRODUCT) {
        pos++, f = factor(), ans = product(ans, f);
      } else if (S[pos] == DIVIDE) {
        pos++, f = factor(), ans = divide(ans, f);
      } else {
        break;
      }
    }
    return ans;
  }
  T expression() {
    T ans = factor();
    for (T f; pos < S.size();) {
      if (S[pos] == PLUS) {
        pos++, f = factor(), ans = plus(ans, f);
      } else if (S[pos] == MINUS) {
        pos++, f = factor(), ans = minus(ans, f);
      } else {
        break;
      }
    }
    return ans;
  }
  int pos = 0;
  string S;
};
template <typename S, typename T>
inline ostream &operator<<(ostream &os, const pair<S, T> &p) {
  return (os << "<" << p.first << "," << p.second << ">");
}

int main() {
  constexpr char C[7] = {'0', '1', '+', '-', '*', '(', ')'};
  string s;
  cin >> s;
  vector<int> p;
  int NUM = 1;
  for (int i = 0; i < s.size(); i++) {
    if (s[i] == '.') {
      p.push_back(i), NUM *= 7;
    }
  }
  const int sz = p.size();
  int ans = -1;
  for (int i = 0; i < NUM; i++) {
    for (int j = 0, num = i; j < sz; j++, num /= 7) {
      s[p[j]] = C[num % 7];
    }
    stack<int> st;
    bool ok = true, num = false;
    for (const char c : s) {
      if (c == '(') {
        if (num) {
          ok = false;
          break;
        }
        st.push(0);
      } else if (c == ')') {
        if (st.empty() or st.top() == 0) {
          ok = false;
          break;
        }
        num = true;
        st.pop();
      } else if (c == '+' or c == '-' or c == '*') {
        if (not num) {
          ok = false;
          break;
        }
        num = false;
        const int n = st.top() + 1;
        st.pop(), st.push(n);
      } else {
        num = true;
      }
    }
    if (not ok) {
      continue;
    }
    const auto sub = SyntaxAnalysis{s}.Expression();
    // show(sub);
    if (sub.first) {
      ans = max(ans, sub.second);
    }
  }
  cout << ans << endl;

  return 0;
}