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

#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <time.h>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

#define LIMIT 1000

enum Type {
  NONE,
  NUMBER,
  OPEN,
  CLOSE,
  ALPHABET,
  POWER,
  SPACE,
  PLUS_MINUS,
};

ll value[3][26], simpson[3];
char buf[1001], mid[20000], line[20000];

ll calc_line() {

  ll n, tmp, op1, work, count, work2;
  char calc;
  stack<ll> NUM, work_num;
  stack<char> OP, work_op;

  bool numFLG, negFLG;

  tmp = 0;
  numFLG = false;
  negFLG = false;

  for (int k = 0; line[k] != '\\0'; k++) {
    if (line[k] >= '0' && line[k] <= '9') {
      numFLG = true;
      tmp = 10 * tmp + (line[k] - '0');

    } else {

      if (numFLG == true) {

        if (negFLG) {
          tmp = -1 * tmp;
          negFLG = false;
        }

        if (OP.empty() == false && (OP.top() == '*' || OP.top() == '/')) {
          calc = OP.top();
          OP.pop();
          op1 = NUM.top();
          NUM.pop();

          if (calc == '*') {
            NUM.push((tmp * op1) % MOD);
          } else {
            NUM.push(op1 / tmp);
          }
        } else {
          NUM.push(tmp % MOD);
        }

        numFLG = false;
        tmp = 0;
      }

      if (line[k] == '+' || line[k] == '*' || line[k] == '/' ||
          line[k] == '(') {
        OP.push(line[k]);
      } else if (line[k] == '-') {

        if (k == 0) {
          if (line[k + 1] != '(') {
            negFLG = true;
          } else {
            NUM.push(-1);
            OP.push('*');
          }
        } else if (line[k - 1] == '(' && line[k + 1] == '(') {
          NUM.push(-1);
          OP.push('*');
        } else if (k > 0 && (line[k - 1] == '+' || line[k - 1] == '-' ||
                             line[k - 1] == '*' || line[k - 1] == '/' ||
                             line[k - 1] == '(')) {
          negFLG = true;
        } else {
          OP.push('-');
        }
      } else if (line[k] == ')') {

        work = NUM.top();
        NUM.pop();
        work_num.push(work);

        count = 0;

        while (true) {
          calc = OP.top();
          OP.pop();
          if (calc == '(')
            break;

          count++;

          work_op.push(calc);

          work = NUM.top();
          NUM.pop();
          work_num.push(work);
        }

        if (count == 0) {
          work = work_num.top();
          work_num.pop();
        } else {

          work = work_num.top();
          work_num.pop();

          while (!work_num.empty()) {
            calc = work_op.top();
            work_op.pop();

            if (calc == '+') {
              work += work_num.top();
            } else if (calc == '-') {
              work -= work_num.top();
            } else if (calc == '*') {
              work *= work_num.top();
            } else {
              work /= work_num.top();
            }
            work %= MOD;
            work_num.pop();
          }
        }

        if (OP.empty() == false && OP.top() == '*') {
          OP.pop();
          work2 = NUM.top();
          NUM.pop();
          work *= work2;
        } else if (OP.empty() == false && OP.top() == '/') {
          OP.pop();
          work2 = NUM.top();
          NUM.pop();
          work = work2 / work;
        }
        work %= MOD;

        NUM.push(work);

      } else {

        work = NUM.top();
        NUM.pop();
        work_num.push(work);

        while (!NUM.empty()) {
          calc = OP.top();
          OP.pop();

          work_op.push(calc);

          work = NUM.top();
          NUM.pop();
          work_num.push(work);
        }

        work = work_num.top();
        work_num.pop();

        while (!work_num.empty()) {
          calc = work_op.top();
          work_op.pop();

          if (calc == '+') {
            work += work_num.top();
          } else if (calc == '-') {
            work -= work_num.top();
          } else if (calc == '*') {
            work *= work_num.top();
          } else {
            work /= work_num.top();
          }
          work %= MOD;
          work_num.pop();
        }

        return (work + MOD) % MOD;
      }
    }
  }
  return -1; // must not reach here
}

void make_mid() {

  int mid_index = 0;
  char pre_ch;

  Type pre = NONE, current;

  for (int i = 0; buf[i] != '\\n' && buf[i] != '\\0';) {

    switch (buf[i]) {
    case ' ':

      while (buf[i] == ' ')
        i++;

      switch (buf[i]) {
      case '(':
        current = OPEN;
        if (pre == NUMBER || pre == ALPHABET || pre == CLOSE) {
          mid[mid_index++] = '*';
        }
        mid[mid_index++] = '(';
        break;
      case ')':
        current = CLOSE;
        mid[mid_index++] = ')';
        break;
      case '^':
        current = POWER;
        break;
      case '+':
      case '-':
        current = PLUS_MINUS;
        mid[mid_index++] = buf[i];
        break;
      case '\\n':
      case '\\0':
        break;
      default:
        if (buf[i] >= '0' && buf[i] <= '9') {
          if (pre == POWER) {
            current = ALPHABET;
            for (int k = 0; k < ((buf[i] - '0') - 1); k++) {
              mid[mid_index++] = '*';
              mid[mid_index++] = pre_ch;
            }
          } else {

            if (pre == NUMBER || pre == ALPHABET || pre == CLOSE) {
              mid[mid_index++] = '*';
            }
            current = NUMBER;
            mid[mid_index++] = buf[i];
          }
        } else {
          current = ALPHABET;

          if (pre == NUMBER || pre == ALPHABET || pre == CLOSE) {
            mid[mid_index++] = '*';
          }
          mid[mid_index++] = buf[i];
          pre_ch = buf[i];
        }
        break;
      }
      i++;
      break;
    case '(':
      current = OPEN;
      if (pre == CLOSE || pre == NUMBER || pre == ALPHABET) {
        mid[mid_index++] = '*';
      }
      mid[mid_index++] = '(';
      i++;
      break;
    case ')':
      current = CLOSE;
      mid[mid_index++] = ')';
      i++;
      break;
    case '^':
      current = POWER;
      i++;
      break;
    case '+':
    case '-':
      current = PLUS_MINUS;
      mid[mid_index++] = buf[i];
      i++;
      break;
    default:
      if (buf[i] >= '0' && buf[i] <= '9') {
        if (pre == POWER) {
          current = ALPHABET;
          for (int k = 0; k < ((buf[i] - '0') - 1); k++) {
            mid[mid_index++] = '*';
            mid[mid_index++] = pre_ch;
          }
        } else {

          if (pre == ALPHABET || pre == CLOSE) {
            mid[mid_index++] = '*';
          }
          current = NUMBER;
          mid[mid_index++] = buf[i];
        }
      } else {
        current = ALPHABET;

        if (pre == NUMBER || pre == ALPHABET || pre == CLOSE) {
          mid[mid_index++] = '*';
        }
        mid[mid_index++] = buf[i];
        pre_ch = buf[i];
      }
      i++;
      break;
    }
    pre = current;
  }
  mid[mid_index] = '\\0';
}

void make_line(int num) {

  int line_index = 0;

  stack<char> S;

  for (int i = 0; mid[i] != '\\0'; i++) {

    if (mid[i] >= 'a' && mid[i] <= 'z') {

      int tmp = value[num][mid[i] - 'a'];

      while (tmp != 0) {
        S.push('0' + (tmp % 10));
        tmp /= 10;
      }

      while (!S.empty()) {
        line[line_index++] = S.top();
        S.pop();
      }
    } else {
      line[line_index++] = mid[i];
    }
  }
  line[line_index] = '=';
  line[line_index + 1] = '\\0';
}

void func() {

  make_mid();

  for (int i = 0; i < 3; i++) {
    make_line(i);
    simpson[i] = calc_line();
  }

  bool FLG;
  ll tmp;

  while (true) {
    fgets(buf, 1000, stdin);
    if (buf[0] == '.')
      break;

    FLG = true;

    make_mid();

    for (int i = 0; i < 3; i++) {
      make_line(i);
      tmp = calc_line();
      if (tmp != simpson[i]) {
        FLG = false;
        printf("no\\n");
        break;
      }
    }
    if (FLG) {
      printf("yes\\n");
    }
  }
  printf(".\\n");
}

int main() {

  ll table[LIMIT];
  for (ll i = 0; i < LIMIT; i++) {
    table[i] = 1;
  }
  table[0] = 0;
  table[1] = 0;

  for (ll i = 2; i <= sqrt(LIMIT); i++) {
    if (table[i] == 1) {
      for (ll k = 2 * i; k < LIMIT; k += i) {
        table[k] = 0;
      }
    }
  }

  ll prime[LIMIT], prime_index = 0;
  for (ll i = 2; i < LIMIT; i++) {
    if (table[i] == 1) {
      prime[prime_index++] = i;
    }
  }

  for (ll i = 0; i < 3; i++) {
    ll base = 7 * (i + 1);

    for (ll k = 0; k < 26; k++) {
      value[i][k] = prime[base + k];
    }
  }

  while (true) {
    fgets(buf, 1000, stdin);
    if (buf[0] == '.')
      break;

    func();
  }

  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <cfloat>
#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <time.h>
#include <vector>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

#define LIMIT 1000

enum Type {
  NONE,
  NUMBER,
  OPEN,
  CLOSE,
  ALPHABET,
  POWER,
  SPACE,
  PLUS_MINUS,
};

ll value[3][26], simpson[3];
char buf[81], mid[2000], line[2000];

ll calc_line() {

  ll n, tmp, op1, work, count, work2;
  char calc;
  stack<ll> NUM, work_num;
  stack<char> OP, work_op;

  bool numFLG, negFLG;

  tmp = 0;
  numFLG = false;
  negFLG = false;

  for (int k = 0; line[k] != '\\0'; k++) {
    if (line[k] >= '0' && line[k] <= '9') {
      numFLG = true;
      tmp = 10 * tmp + (line[k] - '0');

    } else {

      if (numFLG == true) {

        if (negFLG) {
          tmp = -1 * tmp;
          negFLG = false;
        }

        if (OP.empty() == false && (OP.top() == '*' || OP.top() == '/')) {
          calc = OP.top();
          OP.pop();
          op1 = NUM.top();
          NUM.pop();

          if (calc == '*') {
            NUM.push((tmp * op1) % MOD);
          } else {
            NUM.push(op1 / tmp);
          }
        } else {
          NUM.push(tmp);
        }

        numFLG = false;
        tmp = 0;
      }

      if (line[k] == '+' || line[k] == '*' || line[k] == '/' ||
          line[k] == '(') {
        OP.push(line[k]);
      } else if (line[k] == '-') {

        if (k == 0) {
          if (line[k + 1] != '(') {
            negFLG = true;
          } else {
            NUM.push(-1);
            OP.push('*');
          }
        } else if (line[k - 1] == '(' && line[k + 1] == '(') {
          NUM.push(-1);
          OP.push('*');
        } else if (k > 0 && (line[k - 1] == '+' || line[k - 1] == '-' ||
                             line[k - 1] == '*' || line[k - 1] == '/' ||
                             line[k - 1] == '(')) {
          negFLG = true;
        } else {
          OP.push('-');
        }
      } else if (line[k] == ')') {

        work = NUM.top();
        NUM.pop();
        work_num.push(work);

        count = 0;

        while (true) {
          calc = OP.top();
          OP.pop();
          if (calc == '(')
            break;

          count++;

          work_op.push(calc);

          work = NUM.top();
          NUM.pop();
          work_num.push(work);
        }

        if (count == 0) {
          work = work_num.top();
          work_num.pop();
        } else {

          work = work_num.top();
          work_num.pop();

          while (!work_num.empty()) {
            calc = work_op.top();
            work_op.pop();

            if (calc == '+') {
              work += work_num.top();
            } else if (calc == '-') {
              work -= work_num.top();
            } else if (calc == '*') {
              work *= work_num.top();
            } else {
              work /= work_num.top();
            }
            work %= MOD;
            work_num.pop();
          }
        }

        if (OP.empty() == false && OP.top() == '*') {
          OP.pop();
          work2 = NUM.top();
          NUM.pop();
          work *= work2;
        } else if (OP.empty() == false && OP.top() == '/') {
          OP.pop();
          work2 = NUM.top();
          NUM.pop();
          work = work2 / work;
        }
        work %= MOD;

        NUM.push(work);

      } else {

        work = NUM.top();
        NUM.pop();
        work_num.push(work);

        while (!NUM.empty()) {
          calc = OP.top();
          OP.pop();

          work_op.push(calc);

          work = NUM.top();
          NUM.pop();
          work_num.push(work);
        }

        work = work_num.top();
        work_num.pop();

        while (!work_num.empty()) {
          calc = work_op.top();
          work_op.pop();

          if (calc == '+') {
            work += work_num.top();
          } else if (calc == '-') {
            work -= work_num.top();
          } else if (calc == '*') {
            work *= work_num.top();
          } else {
            work /= work_num.top();
          }
          work %= MOD;
          work_num.pop();
        }

        return work;
      }
    }
  }
  return -1; // must not reach here
}

void make_mid() {

  int mid_index = 0;
  char pre_ch;

  Type pre = NONE, current;

  for (int i = 0; buf[i] != '\\n' && buf[i] != '\\0';) {

    switch (buf[i]) {
    case ' ':

      while (buf[i] == ' ')
        i++;

      switch (buf[i]) {
      case '(':
        current = OPEN;
        if (pre == NUMBER || pre == ALPHABET || pre == CLOSE) {
          mid[mid_index++] = '*';
        }
        mid[mid_index++] = '(';
        break;
      case ')':
        current = CLOSE;
        mid[mid_index++] = ')';
        break;
      case '^':
        current = POWER;
        break;
      case '+':
      case '-':
        current = PLUS_MINUS;
        mid[mid_index++] = buf[i];
        break;
      case '\\n':
      case '\\0':
        break;
      default:
        if (buf[i] >= '0' && buf[i] <= '9') {
          if (pre == POWER) {
            current = ALPHABET;
            for (int k = 0; k < ((buf[i] - '0') - 1); k++) {
              mid[mid_index++] = '*';
              mid[mid_index++] = pre_ch;
            }
          } else {

            if (pre == NUMBER || pre == ALPHABET || pre == CLOSE) {
              mid[mid_index++] = '*';
            }
            current = NUMBER;
            mid[mid_index++] = buf[i];
          }
        } else {
          current = ALPHABET;

          if (pre == NUMBER || pre == ALPHABET || pre == CLOSE) {
            mid[mid_index++] = '*';
          }
          mid[mid_index++] = buf[i];
          pre_ch = buf[i];
        }
        break;
      }
      i++;
      break;
    case '(':
      current = OPEN;
      if (pre == CLOSE || pre == NUMBER || pre == ALPHABET) {
        mid[mid_index++] = '*';
      }
      mid[mid_index++] = '(';
      i++;
      break;
    case ')':
      current = CLOSE;
      mid[mid_index++] = ')';
      i++;
      break;
    case '^':
      current = POWER;
      i++;
      break;
    case '+':
    case '-':
      current = PLUS_MINUS;
      mid[mid_index++] = buf[i];
      i++;
      break;
    default:
      if (buf[i] >= '0' && buf[i] <= '9') {
        if (pre == POWER) {
          current = ALPHABET;
          for (int k = 0; k < ((buf[i] - '0') - 1); k++) {
            mid[mid_index++] = '*';
            mid[mid_index++] = pre_ch;
          }
        } else {

          if (pre == ALPHABET || pre == CLOSE) {
            mid[mid_index++] = '*';
          }
          current = NUMBER;
          mid[mid_index++] = buf[i];
        }
      } else {
        current = ALPHABET;

        if (pre == NUMBER || pre == ALPHABET || pre == CLOSE) {
          mid[mid_index++] = '*';
        }
        mid[mid_index++] = buf[i];
        pre_ch = buf[i];
      }
      i++;
      break;
    }
    pre = current;
  }
  mid[mid_index] = '\\0';
}

void make_line(int num) {

  int line_index = 0;

  stack<char> S;

  for (int i = 0; mid[i] != '\\0'; i++) {

    if (mid[i] >= 'a' && mid[i] <= 'z') {

      int tmp = value[num][mid[i] - 'a'];

      while (tmp != 0) {
        S.push('0' + (tmp % 10));
        tmp /= 10;
      }

      while (!S.empty()) {
        line[line_index++] = S.top();
        S.pop();
      }
    } else {
      line[line_index++] = mid[i];
    }
  }
  line[line_index] = '=';
  line[line_index + 1] = '\\0';
}

void func() {

  make_mid();

  for (int i = 0; i < 3; i++) {
    make_line(i);
    simpson[i] = calc_line();
  }

  bool FLG;
  ll tmp;

  while (true) {
    fgets(buf, 80, stdin);
    if (buf[0] == '.')
      break;

    FLG = true;

    make_mid();

    for (int i = 0; i < 3; i++) {
      make_line(i);
      tmp = calc_line();
      if (tmp != simpson[i]) {
        FLG = false;
        printf("no\\n");
        break;
      }
    }
    if (FLG) {
      printf("yes\\n");
    }
  }
  printf(".\\n");
}

int main() {

  ll table[LIMIT];
  for (ll i = 0; i < LIMIT; i++) {
    table[i] = 1;
  }
  table[0] = 0;
  table[1] = 0;

  for (ll i = 2; i <= sqrt(LIMIT); i++) {
    if (table[i] == 1) {
      for (ll k = 2 * i; k < LIMIT; k += i) {
        table[k] = 0;
      }
    }
  }

  ll prime[LIMIT], prime_index = 0;
  for (ll i = 2; i < LIMIT; i++) {
    if (table[i] == 1) {
      prime[prime_index++] = i;
    }
  }

  for (ll i = 0; i < 3; i++) {
    ll base = 7 * (i + 1);

    for (ll k = 0; k < 26; k++) {
      value[i][k] = prime[base + k];
    }
  }

  while (true) {
    fgets(buf, 80, stdin);
    if (buf[0] == '.')
      break;

    func();
  }

  return 0;
}