Problem p01755 (C++) — buggy submission, verdict: Time Limit Exceeded

/*
 * 2643.cc: AI
 */

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

/* constant */

const int MAX_H = 50;
const int MAX_W = 50;
const int MAX_PC = 2000000;

const int INF = 1 << 30;

const int dxs[] = {1, 0, -1, 0}, dys[] = {0, -1, 0, 1};

/* typedef */

/* global variables */

int h, w;
int sx, sy, gx, gy, di;
string flds[MAX_H];
int ans, pc;

/* subroutines */

void stop(int x) {
  printf("%d\\n", x);
  exit(0);
}

bool condition(string &s, int &pos, bool run) {
  bool no = false;
  if (s[pos] == '~')
    no = true, pos++;

  char op = s[pos++];
  if (!run)
    return false;

  switch (op) {
  case 'N':
    return (di == 1) ^ no;
  case 'E':
    return (di == 0) ^ no;
  case 'S':
    return (di == 3) ^ no;
  case 'W':
    return (di == 2) ^ no;
  case 'C':
    return (flds[sy + dys[di]][sx + dxs[di]] == '#') ^ no;
  }
  return true ^ no;
}

void prog(string &s, int &pos, bool run) {
  while (pos < s.size() && s[pos] != ']' && s[pos] != '}') {
    // 'if' statement
    if (s[pos] == '[') {
      pos++; // '['
      bool cf = condition(s, pos, run);
      prog(s, pos, run && cf);
      pos++; // ']'

      if (++pc >= MAX_PC)
        stop(-1);
      continue;
    }

    // 'while' statement
    if (s[pos] == '{') {
      pos++; // '{'
      int pos0 = pos;
      while (condition(s, pos, run)) {
        prog(s, pos, true);
        pos = pos0;
        if (++pc >= MAX_PC)
          stop(-1);
      }
      prog(s, pos, false);
      pos++; // '}'
      continue;
    }

    // 'action' statement
    char op = s[pos++];
    if (run) {
      int x0, y0;

      switch (op) {
      case '^':
        x0 = sx + dxs[di], y0 = sy + dys[di];
        if (flds[y0][x0] == '.')
          sx = x0, sy = y0;
        break;
      case 'v':
        x0 = sx - dxs[di], y0 = sy - dys[di];
        if (flds[y0][x0] == '.')
          sx = x0, sy = y0;
        break;
      case '<':
        di = (di + 1) & 3;
        break;
      case '>':
        di = (di + 3) & 3;
        break;
      }
      ans++;
      // printf("action(%c): (%d,%d)[%d]\\n", op, sx, sy, di);

      if (sx == gx && sy == gy)
        stop(ans);
      if (++pc >= MAX_PC)
        stop(-1);
    }
  }
}

/* main */

int main() {
  cin >> h >> w;

  for (int y = 0; y < h; y++) {
    cin >> flds[y];
    for (int x = 0; x < w; x++) {
      switch (flds[y][x]) {
      case 's':
        flds[y][x] = '.';
        sx = x;
        sy = y;
        break;
      case 'g':
        flds[y][x] = '.';
        gx = x;
        gy = y;
        break;
      }
    }
  }
  di = 1;

  string s;
  cin >> s;

  int pos = 0;
  prog(s, pos, true);

  puts("-1");
  return 0;
}

Error: TLE

Fixed submission:

/*
 * 2643.cc: AI
 */

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

/* constant */

const int MAX_H = 50;
const int MAX_W = 50;
const int MAX_ANS = 1000000;

const int INF = 1 << 30;

const int dxs[] = {1, 0, -1, 0}, dys[] = {0, -1, 0, 1};

/* typedef */

/* global variables */

int h, w;
int sx, sy, gx, gy, di;
string flds[MAX_H];
int ans;

/* subroutines */

bool condition(string &s, int &pos, bool run) {
  bool no = false;
  if (s[pos] == '~')
    no = true, pos++;

  char op = s[pos++];
  if (!run)
    return false;

  switch (op) {
  case 'N':
    return (di == 1) ^ no;
  case 'E':
    return (di == 0) ^ no;
  case 'S':
    return (di == 3) ^ no;
  case 'W':
    return (di == 2) ^ no;
  case 'C':
    return (flds[sy + dys[di]][sx + dxs[di]] == '#') ^ no;
  }
  return true ^ no;
}

void prog(string &s, int &pos, bool run) {
  while (pos < s.size() && s[pos] != ']' && s[pos] != '}') {
    // 'if' statement
    if (s[pos] == '[') {
      pos++; // '['
      bool cf = condition(s, pos, run);
      prog(s, pos, run && cf);
      pos++; // ']'
      return;
    }

    // 'while' statement
    if (s[pos] == '{') {
      pos++; // '{'
      int pos0 = pos;
      while (condition(s, pos, run)) {
        prog(s, pos, true);
        pos = pos0;
      }
      prog(s, pos, false);
      pos++; // '}'
    }

    // 'action' statement
    char op = s[pos++];
    if (run) {
      int x0, y0;

      switch (op) {
      case '^':
        x0 = sx + dxs[di], y0 = sy + dys[di];
        if (flds[y0][x0] == '.')
          sx = x0, sy = y0;
        break;
      case 'v':
        x0 = sx - dxs[di], y0 = sy - dys[di];
        if (flds[y0][x0] == '.')
          sx = x0, sy = y0;
        break;
      case '<':
        di = (di + 1) & 3;
        break;
      case '>':
        di = (di + 3) & 3;
        break;
      }
      ans++;
      // printf("action(%c): (%d,%d)[%d]\\n", op, sx, sy, di);

      if (sx == gx && sy == gy) {
        printf("%d\\n", ans);
        exit(0);
      }
      if (ans > MAX_ANS) {
        puts("-1");
        exit(0);
      }
    }
  }
}

/* main */

int main() {
  cin >> h >> w;

  for (int y = 0; y < h; y++) {
    cin >> flds[y];
    for (int x = 0; x < w; x++) {
      switch (flds[y][x]) {
      case 's':
        flds[y][x] = '.';
        sx = x;
        sy = y;
        break;
      case 'g':
        flds[y][x] = '.';
        gx = x;
        gy = y;
        break;
      }
    }
  }
  di = 1;

  string s;
  cin >> s;

  int pos = 0;
  prog(s, pos, true);

  puts("-1");
  return 0;
}