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

#include <algorithm>
#include <iostream>
#include <stack>
#include <string>
#include <vector>
// #define NDEBUG
#include <cassert>
using namespace std;

// N:0 E:1 S:2 W:3
const int dx[] = {0, 1, 0, -1};
const int dy[] = {-1, 0, 1, 0};

typedef pair<int, int> pii;
#define y first
#define x second

int H, W;
vector<string> stage;
string pg;
vector<int> jmp;

bool visit[60][60][1100][4];
int dir;
pii robo;

int ans;

bool valid_range(int h, int w) { return 0 <= h && h < H && 0 <= w && w < W; }

void update(int &pc, int nex_pc) {
  // cout << robo.y << " " << robo.x << " " << pc << " " << dir << endl;
  assert(pc != nex_pc);
  if (visit[robo.y][robo.x][pc][dir]) {
    cout << -1 << endl;
    exit(0);
  }
  visit[robo.y][robo.x][pc][dir] = true;
  pc = nex_pc;
}

bool check(int &pc) {
  bool res, inv;
  inv = false;
  if (pg[pc] == '~') {
    inv = true;
    update(pc, pc + 1);
  }
  int nx, ny;
  ny = robo.y + dy[dir];
  nx = robo.x + dx[dir];
  switch (pg[pc]) {
  case 'C':
    res = stage[ny][nx] == '#';
    break;
  case 'N':
    res = dir == 0;
    break;
  case 'E':
    res = dir == 1;
    break;
  case 'S':
    res = dir == 2;
    break;
  case 'W':
    res = dir == 3;
    break;
  case 'T':
    res = true;
    break;
  default:
    assert(0);
  }
  if (inv)
    return !res;
  return res;
}

bool solve(int &pc) {
  int res = 0;
  while (pc < pg.size() && pg[pc] != ']' && pg[pc] != '}') {
    if (stage[robo.y][robo.x] == 'g')
      return true;
    if (pg[pc] == '[') {
      bool flg;
      int tmp;
      tmp = jmp[pc];
      update(pc, pc + 1);
      flg = check(pc);
      if (flg) {
        update(pc, pc + 1);
        if (solve(pc))
          return true;
        assert(pc == tmp);
        update(pc, pc + 1);
      } else {
        update(pc, tmp + 1);
      }
    } else if (pg[pc] == '{') {
      int tmp = jmp[pc];
      bool flg = true;
      update(pc, pc + 1);
      while (check(pc)) {
        update(pc, pc + 1);
        if (solve(pc))
          return true;
        update(pc, jmp[pc]);
        update(pc, pc + 1);
      }
      update(pc, tmp + 1);
    } else {
      int nx, ny;
      nx = robo.x;
      ny = robo.y;
      switch (pg[pc]) {
      case '^':
        ny = robo.y + dy[dir];
        nx = robo.x + dx[dir];
        ans++;
        break;
      case 'v':
        ny = robo.y + dy[dir + 2 & 3];
        nx = robo.x + dx[dir + 2 & 3];
        ans++;
        break;
      case '<':
        dir = dir - 1 + 4 & 3;
        ans++;
        break;
      case '>':
        dir = dir + 1 + 4 & 3;
        ans++;
        break;
      default:
        assert(0);
      }
      if (valid_range(ny, nx) && stage[ny][nx] != '#') {
        robo.y = ny;
        robo.x = nx;
      }
      update(pc, pc + 1);
    }
  }
  if (stage[robo.y][robo.x] == 'g')
    return true;
  return false;
}

int main() {
  cin >> H >> W;
  stage.resize(H);
  for (int i = 0; i < H; i++)
    cin >> stage[i];
  cin >> pg;

  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      if (stage[i][j] == 's') {
        robo.y = i;
        robo.x = j;
        stage[i][j] = '.';
      }
    }
  }
  jmp.resize(pg.size());
  stack<int> stk;
  for (int i = 0; i < pg.size(); i++) {
    if (pg[i] == '[' || pg[i] == '{') {
      stk.push(i);
    } else if (pg[i] == ']' || pg[i] == '}') {
      int tmp;
      tmp = stk.top();
      stk.pop();
      jmp[i] = tmp;
      jmp[tmp] = i;
    }
  }

  int tmp;
  bool res;
  tmp = 0;
  res = solve(tmp);
  if (res)
    cout << ans << endl;
  else
    cout << -1 << endl;
}

Error: -6
87d84f89-ab35-45fc-a818-402041ffef2a.out: /home/alex/Documents/bug-detection/input/Project_CodeNet/data/p01755/C++/s631907123.cpp:36: void update(int&, int): Assertion `pc == nex_pc' failed.


Fixed submission:

#include <algorithm>
#include <iostream>
#include <stack>
#include <string>
#include <vector>
// #define NDEBUG
#include <cassert>
using namespace std;

// N:0 E:1 S:2 W:3
const int dx[] = {0, 1, 0, -1};
const int dy[] = {-1, 0, 1, 0};

typedef pair<int, int> pii;
#define y first
#define x second

int H, W;
vector<string> stage;
string pg;
vector<int> jmp;

bool visit[60][60][1100][4];
int dir;
pii robo;

int ans;

bool valid_range(int h, int w) { return 0 <= h && h < H && 0 <= w && w < W; }

void update(int &pc, int nex_pc) {
  // cout << robo.y << " " << robo.x << " " << pc << " " << dir << endl;
  assert(pc == nex_pc);
  if (visit[robo.y][robo.x][nex_pc][dir]) {
    cout << -1 << endl;
    exit(0);
  }
  visit[robo.y][robo.x][nex_pc][dir] = true;
  pc = nex_pc;
}

bool check(int &pc) {
  bool res, inv;
  inv = false;
  if (pg[pc] == '~') {
    inv = true;
    update(pc, pc + 1);
  }
  int nx, ny;
  ny = robo.y + dy[dir];
  nx = robo.x + dx[dir];
  switch (pg[pc]) {
  case 'C':
    res = stage[ny][nx] == '#';
    break;
  case 'N':
    res = dir == 0;
    break;
  case 'E':
    res = dir == 1;
    break;
  case 'S':
    res = dir == 2;
    break;
  case 'W':
    res = dir == 3;
    break;
  case 'T':
    res = true;
    break;
  default:
    assert(0);
  }
  if (inv)
    return !res;
  return res;
}

bool solve(int &pc) {
  int res = 0;
  while (pc < pg.size() && pg[pc] != ']' && pg[pc] != '}') {
    if (stage[robo.y][robo.x] == 'g')
      return true;
    if (pg[pc] == '[') {
      bool flg;
      int tmp;
      tmp = jmp[pc];
      update(pc, pc + 1);
      flg = check(pc);
      if (flg) {
        update(pc, pc + 1);
        if (solve(pc))
          return true;
        assert(pc == tmp);
        update(pc, pc + 1);
      } else {
        update(pc, tmp + 1);
      }
    } else if (pg[pc] == '{') {
      int tmp = jmp[pc];
      bool flg = true;
      update(pc, pc + 1);
      while (check(pc)) {
        update(pc, pc + 1);
        if (solve(pc))
          return true;
        update(pc, jmp[pc]);
        update(pc, pc + 1);
      }
      update(pc, tmp + 1);
    } else {
      int nx, ny;
      nx = robo.x;
      ny = robo.y;
      switch (pg[pc]) {
      case '^':
        ny = robo.y + dy[dir];
        nx = robo.x + dx[dir];
        ans++;
        break;
      case 'v':
        ny = robo.y + dy[dir + 2 & 3];
        nx = robo.x + dx[dir + 2 & 3];
        ans++;
        break;
      case '<':
        dir = dir - 1 + 4 & 3;
        ans++;
        break;
      case '>':
        dir = dir + 1 + 4 & 3;
        ans++;
        break;
      default:
        assert(0);
      }
      if (valid_range(ny, nx) && stage[ny][nx] != '#') {
        robo.y = ny;
        robo.x = nx;
      }
      update(pc, pc + 1);
    }
  }
  return false;
}

int main() {
  cin >> H >> W;
  stage.resize(H);
  for (int i = 0; i < H; i++)
    cin >> stage[i];
  cin >> pg;

  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      if (stage[i][j] == 's') {
        robo.y = i;
        robo.x = j;
        stage[i][j] = '.';
      }
    }
  }
  jmp.resize(pg.size());
  stack<int> stk;
  for (int i = 0; i < pg.size(); i++) {
    if (pg[i] == '[' || pg[i] == '{') {
      stk.push(i);
    } else if (pg[i] == ']' || pg[i] == '}') {
      int tmp;
      tmp = stk.top();
      stk.pop();
      jmp[i] = tmp;
      jmp[tmp] = i;
    }
  }

  int tmp;
  bool res;
  tmp = 0;
  res = solve(tmp);
  if (res)
    cout << ans << endl;
  else
    cout << -1 << endl;
}