Problem:
問題名 Zero division checker

森下さんは困っていました... 姉原さんにプログラムを書いてもらったのですが、そのプログラムがクラッシュするのです。

姉原さんに書いてもらったのは、逆ポーランド記法の式を読んで、その計算結果を出力するプログラムで、クラッシュログによると、 0 で割り算をしてしまったのが原因のようです。これは、森下さんが間違った式を入力してしまったからかもしれませんし、もしかしたら、もしかしたら、姉原さんの書いたプログラムにバグがあるのかもしれません。

姉原さんの書いたプログラムを読んでみようと思いましたが、姉原さんのプログラムはアセンブリというよくわからないことばで書かれているようで、見ているだけで頭がガンガンしてきます。

そこで、森下さんはあなたに、式が間違っていないかどうか調べるプログラムを書いてもらうことにしました。式が間違っている、とは、その式に従って計算すると、 0 での割り算をしてしまう可能性のあることをいいます。

なお、姉原さんの書いたコードはとてもふるいコンピューターで動くもので、加減乗除は整数で行い、結果は 8 bit の符号なし整数として保存されます。
例えば、255+1 は 0 になってしまうし、3/2 は 1 になります。

あ、姉原さんにはないしょですよ。

(参考)逆ポーランド記法で表された式を計算する、擬似コード

s = 空のスタック
n = 式の要素数
for i in 1..n:
if 式のi番目の要素が整数:
sにその整数をプッシュする
if 式のi番目の要素が変数:
sにその変数の値をプッシュする
if 式のi番目の要素が演算子:
sから値をポップし、bとする
sから値をポップし、aとする
if 演算子が'+':
r = (a + b) % 256 とする
if 演算子が'-':
r = (a - b + 256) % 256 とする
if 演算子が'*':
r = (a * b) % 256 とする
if 演算子が'/':
r = (a / b) % 256 とする
sにrをプッシュする
sから値をポップし、式の計算結果とする

Input

m

name1 lb1 ub1

...

namem lbm ubm

n

e1 e2 ... en

0 ≤ m ≤ 100

0 ≤ lbi ≤ ubi ≤ 255

1 ≤ namei (1 ≤ i ≤ m) の長さ ≤ 20

1 ≤ n ≤ 100

m は変数の数、namei, lbi, ubi はそれぞれ変数iの名前、下限、上限を表します。

n は式に含まれる要素の数を表し、ei は式の i 番目の要素を表します。

各変数は式の中に高々1回しか現れません。

Output

式が間違っているときにはerror、間違っていないときにはcorrectと一行で出力してください。

Sample Input 1

1
a 1 10
3
10 a /

Output for the Sample Input 1

correct

Sample Input 2

2
a 1 10
b 1 10
5
1 a b - /

Output for the Sample Input 2

error

Sample Input 3

1
a 0 255
7
1 a 2 * 1 + /

Output for the Sample Input 3

correct

Solution in C++ (judge verdict: Runtime Error)

#include<iostream>
#include<cstdio>
#include<functional>
#include<cstdlib>
#include<stdexcept>
#include<numeric>
#include<cmath>
#include<fstream>
#include<memory>
#include<algorithm>
#include<cstring>
#include<ctime>
#include<deque>
#include<sstream>
#include<iomanip>
#include<sstream>
#include<vector>
#include<queue>
#include<stack>
#include<string>
#include<climits>
#include<map>
#include<set>
#include<list>
#include<cassert>
#include<deque>
#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define INF 1<<27
#define all(n) n.begin(),n.end()
#define F first
#define iter(c) __typeof__((c).begin())
#define foreach(i,c) for(iter(c) i=(c).begin();i!=(c).end();++i)
#define S second
#define ppins(a,b,c,d) PP(P(a,b),P(c,d))
#define pb push_back
#define My "NARIYOSHI_XX"
#define pf push_front
#define LIM 100000
using namespace std;
typedef pair<int,int> P;
typedef pair<P,P> PP;
typedef long long ll;
typedef unsigned long long ull;

bool calc(set<int>& B,set<int>& A,string ope,stack<set<int> >& ele,map<string,set<int> >& index)
{
  set<int> C;
  for(set<int>::iterator it_B = B.begin();it_B != B.end();it_B++)
    {
      for(set<int>::iterator it_A = A.begin();it_A != A.end();it_A++)
	{
	  if(ope == "+")
	    {
	      C.insert(((*it_A)+(*it_B))%256);
	    }
	  else if(ope == "-")
	    {
	      C.insert(((*it_A)-(*it_B)+256)%256);
	    }
	  else if(ope == "*")
	    {
	      C.insert(((*it_A)*(*it_B))%256);
	    }
	  else if(ope == "/")
	    {
	      if(!(*it_B))
		{
	
		  return false; 
		}
	      C.insert(((*it_A)/(*it_B))%256);
	    }
	  else 
	    assert(false);
	}
    }
  index[My] = C;
  ele.push(C);
  return true;
}

int main(){
  int m,n;
  map<string,set<int> > index;
  stack<set<int> > ele;
  deque<string> st;
  bool fin = false;

  cin >> m;
  for(int i=0;i<m;i++)
    {
      string name;
      int lb,ub;
      cin >> name >> lb >> ub;
      for(int j = lb;j <= ub;j++)
	index[name].insert(j);
    }

  cin >> n;
  for(int i=0;i<n;i++)
    {
      string e;
      cin >> e;
     
      if(e != "/" && e != "*" && e != "-" && e != "+")
	{
	  if(index.find(e) != index.end())
	    {
	      ele.push(index[e]);
	    }
	  else
	    {
	      set<int> FAGS;
	      FAGS.insert((atoi)(e.c_str()));
	      ele.push(FAGS);
	    }
	}
      else 
	{
	  set<int> A,B;
	  B = ele.top(),ele.pop();
	  A = ele.top(),ele.pop();
	  if(!calc(B,A,e,ele,index))
	    fin = true;	    
	}

    }

  if(fin)
    {
      cout << "error" << endl;
      return 0;
    }
  
    cout << "correct" << endl;

return 0;
}