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

#include <assert.h>
#include <functional>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main(int argc, char *argv[]) {
  auto parse = [](const string &exp) {
    int i = 0;
    function<int()> pp = [&exp, &i, &pp]() {
      char c = exp[i++];
      switch (c) {
      case '0': {
        return 0x0000;
      }
      case '1': {
        return 0xffff;
      }
      case 'a': {
        return 0xaaaa;
      } // 1010 1010 1010 1010
      case 'b': {
        return 0xcccc;
      } // 1100 1100 1100 1100
      case 'c': {
        return 0xf0f0;
      } // 1111 0000 1111 0000
      case 'd': {
        return 0xff00;
      } // 1111 1111 0000 0000
      case '-': {
        return (~pp()) & 0xffff;
      }
      case '(': {
        int a = pp();
        c = exp[i++];
        switch (c) {
        case '^': {
          int b = a ^ pp(); /* ')' */
          i++;
          return b;
        }
        case '*': {
          int b = a & pp(); /* ')' */
          i++;
          return b;
        }
        }
        assert(false);
      }
      }
    };
    return pp();
  };
  /* building answers from the shortest ones
     1: 0,1,a,b,c,d
     2: -a,-b-c-d
     3: x
     4: x
     5: (_*_), (_^_)   # 1+1+3
     6: (_*__), (_^__), -(_*_), -(_^_)
     7: -(_*__), -(_^__)
     8: (__*__), (__^__)
     9: (_*_____), (_^_____)
     ...
  */
  vector<string> ans(1 << 16, ""); // redundant. only the length is necessary.
  vector<vector<int>> sss;
  sss.push_back({});
  vector<int> ss1;
  for (string s : {"0", "1", "a", "b", "c", "d"}) {
    int t = parse(s);
    ss1.push_back(t);
    ans[t] = s;
  }
  sss.push_back(move(ss1));
  const string str_neg = "-";
  const string str_xor = "^";
  const string str_and = "*";
  for (int i = 2; i <= 16; i++) {
    // cout << "building " << i << endl;
    vector<int> is;
    // negation
    for (int s : sss[i - 1]) {
      int p = (~s) & 0xffff;
      if (ans[p] == "") {
        string str = "-" + ans[s];
        ans[p] = move(str);
        is.push_back(p);
        // cout << "pushed " << ans[p] << endl;
      }
    }
    // combination
    for (int j = 1; j < i - 3; j++) {
      int k = i - j - 3; // i.e., i = k + j + 3
      for (int s : sss[j]) {
        for (int t : sss[k]) {
          {
            int p = s ^ t;
            if (ans[p] == "") {
              string str = "(" + ans[s] + "^" + ans[t] + ")";
              ans[p] = move(str);
              is.push_back(p);
              // cout << "pushed " << ans[p] << endl;
            }
          }
          {
            int p = s & t;
            if (ans[p] == "") {
              string str = "(" + ans[s] + "*" + ans[t] + ")";
              ans[p] = move(str);
              is.push_back(p);
              // cout << "pushed " << ans[p] << endl;
            }
          }
        }
      }
    }
    sss.push_back(is);
  }
  for (;;) {
    string str;
    cin >> str;
    if (str == ".")
      break;
    // cout << "read: " << setfill('0') << setw(4) <<  hex << parse(str) <<
    // endl;
    cout << ans[parse(str)].length() << endl;
  }
  return 0;
}

Error: 0

Fixed submission:

#include <assert.h>
#include <functional>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main(int argc, char *argv[]) {
  auto parse = [](const string &exp) {
    int i = 0;
    function<int()> pp = [&exp, &i, &pp]() {
      char c = exp[i++];
      switch (c) {
      case '0': {
        return 0x0000;
      }
      case '1': {
        return 0xffff;
      }
      case 'a': {
        return 0xaaaa;
      } // 1010 1010 1010 1010
      case 'b': {
        return 0xcccc;
      } // 1100 1100 1100 1100
      case 'c': {
        return 0xf0f0;
      } // 1111 0000 1111 0000
      case 'd': {
        return 0xff00;
      } // 1111 1111 0000 0000
      case '-': {
        return ~pp();
      }
      case '(': {
        int a = pp();
        c = exp[i++];
        switch (c) {
        case '^': {
          int b = a ^ pp(); /* ')' */
          i++;
          return b;
        }
        case '*': {
          int b = a & pp(); /* ')' */
          i++;
          return b;
        }
        }
        assert(false);
      }
      }
    };
    return pp();
  };
  /* building answers from the shortest ones
     1: 0,1,a,b,c,d
     2: -a,-b-c-d
     3: x
     4: x
     5: (_*_), (_^_)   # 1+1+3
     6: (_*__), (_^__), -(_*_), -(_^_)
     7: -(_*__), -(_^__)
     8: (__*__), (__^__)
     9: (_*_____), (_^_____)
     ...
  */
  vector<string> ans(1 << 16, ""); // redundant. only the length is necessary.
  vector<vector<int>> sss;
  sss.push_back({});
  vector<int> ss1;
  for (string s : {"0", "1", "a", "b", "c", "d"}) {
    int t = parse(s);
    ss1.push_back(t);
    ans[t] = s;
  }
  sss.push_back(move(ss1));
  const string str_neg = "-";
  const string str_xor = "^";
  const string str_and = "*";
  for (int i = 2; i <= 16; i++) {
    // cout << "building " << i << endl;
    vector<int> is;
    // negation
    for (int s : sss[i - 1]) {
      int p = (~s) & 0xffff;
      if (ans[p] == "") {
        string str = "-" + ans[s];
        ans[p] = move(str);
        is.push_back(p);
        // cout << "pushed " << ans[p] << endl;
      }
    }
    // combination
    for (int j = 1; j < i - 3; j++) {
      int k = i - j - 3; // i.e., i = k + j + 3
      for (int s : sss[j]) {
        for (int t : sss[k]) {
          {
            int p = s ^ t;
            if (ans[p] == "") {
              string str = "(" + ans[s] + "^" + ans[t] + ")";
              ans[p] = move(str);
              is.push_back(p);
              // cout << "pushed " << ans[p] << endl;
            }
          }
          {
            int p = s & t;
            if (ans[p] == "") {
              string str = "(" + ans[s] + "*" + ans[t] + ")";
              ans[p] = move(str);
              is.push_back(p);
              // cout << "pushed " << ans[p] << endl;
            }
          }
        }
      }
    }
    sss.push_back(is);
  }
  for (;;) {
    string str;
    cin >> str;
    if (str == ".")
      break;
    // cout << setfill('0') << setw(4) <<  hex << parse(str) << endl;
    cout << ans[parse(str)].length() << endl;
  }
  return 0;
}