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: Time Limit Exceeded)

/*
  AOJ 2435
  Title:  Zero Division Checker
  @kankichi573
*/
#include <stdio.h>
#include <string.h>
#include <setjmp.h>

jmp_buf jb;
char variable[100][21];
char expression[100][4];

int m,n;
struct uplow {
  unsigned long long usll[4];
}var[100],stack[100];
int sp;

void clear_val(struct uplow *x)
{
  x->usll[0]=x->usll[1]=x->usll[2]=x->usll[3]=0ULL;
}

void set_val(struct uplow *x,unsigned char num)
{
  x->usll[num/64] |= (1ULL<<(num % 64));
}
int is_val(struct uplow x,unsigned char num)
{
  int ret= (x.usll[num/64] & (1ULL<<(num % 64)))?1:0;
  return(ret);
}
void show_val(struct uplow x)
{
  int i;
  for(i=0;i<=255;i++)
    if(is_val(x,(unsigned char)i))
      printf("%d:",i);
  printf("\n");
}
void dump_stack()
{
  int i;
  for(i=0;i<sp;i++)
    show_val(stack[i]);
}
void dump_variable()
{
  int i;
  printf("%d variables\n",n);
  for(i=0;i<n;i++)
    show_val(var[i]);
}

int is_number(char *s)
{
  while(*s)
    {
      if(*s >= '0' && *s <= '9')
	 s++;
      else
	return(0); 
    }
  return(1);
}
int is_variable(char *s)
{
  while(*s)
    {
      if(isalpha(*s))
	 s++;
      else
	return(0); 
    }
  return(1);
}

struct uplow bin_operator(struct uplow arg1,struct uplow arg2,char op)
{
  struct uplow ret;
  int i,j;
  unsigned char res;

  if(op=='/' && is_val(arg2,0)) //div by zero
    longjmp(jb,1);
  clear_val(&ret);
  
  for(i=0;i<256;i++)
    if(is_val(arg1,(unsigned char)i))
      for(j=0;j<256;j++)
	if(is_val(arg2,(unsigned char)j))
	  {
	    if(op=='+')
	      res=i+j;
	    else if(op=='-')
	      res=i-j;
	    else if(op=='*')
	      res=i*j;
	    else if(op=='/')
	      res=i/j;
	    set_val(&ret,res);
	  }
  return(ret);
}

char operator[]="+-*/";

void eval_forth()
{
  int i,j,opn;
  char *el;
  struct uplow work,work1,work2;

  for(i=0;i<m;i++)
    {
      el=&expression[i][0];
      if(is_number(el))
	{
	  clear_val(&work);
	  set_val(&work,atoi(el));
	  stack[sp]=work;
	  sp++;
	}
      else if(is_variable(el))
	{
	  for(j=0;j<n;j++)
	    if(0==strcmp(&variable[j][0],el))
	      {
		work = var[j]; 
		stack[sp]=work;
		sp++;
	      }
	}
      else
	{
	  work1=stack[sp-2];
	  work2=stack[sp-1];
  
	  work=bin_operator(work1,work2,*el);
	  sp--;
	  stack[sp-1]=work;
	}
    }
}

int solve()
{
  sp=0;
  if(setjmp( jb ) == 0 ) 
    eval_forth();
  else
    return(0);
    
  return(1);
}
main()
{
  int i,ret,a,b;
  unsigned char j;

  memset(var,0,sizeof(long long)*4*100);
  scanf("%d",&n);
  for(i=0;i<n;i++)
    {
      scanf("%s %d %d",&variable[i][0],&a,&b);
      for(j=a;j<=b;j++)
	set_val(&var[i],j);
    }
  //dump_variable();
  scanf("%d",&m);
  for(i=0;i<m;i++)
    scanf("%s",&expression[i][0]);
  
  ret=solve();
  //dump_stack();
  printf("%s\n",ret?"correct":"error");
  
  return(0);
}