Problem:
Problem D: Dimensional Analysis
量の次元とは、相異なる量の間の関係式から具体的数値を無視して量の種類とそのべき乗だけに着目した概念である。具体的には定数係数を無視した等式として、次元の関係式を表す。すなわち、量 q の次元を[ q ]と表せば、以下のようないくつかの次元の関係式が例示できる。
[面積] = [長さ]
2
[体積] = [長さ]
3
[速さ] = [長さ][時間]
-1
[加速度] = [長さ][時間]
-2
[力] = [質量][長さ][時間]
-2
[仕事] = [質量][長さ]
2
[時間]
-2
(Wikipedia 「量」より抜粋 URL http://ja.wikipedia.org/wiki/%E9%87%8F)
量は基本量と組み立て量に分類される。
この問題ではn個の基本量とm個の組立量が与えられる。
与えられたm個の組立量の次元はすべてn個の基本量の次元の積で表すことができる。
また基本量の次元の積で２つの次元を表したとき、各基本量の指数がすべて一致すればその二つの次元は等しいと言える。
式と変数の量と量の次元についての情報が与えられるので、
式を解析しその次元が表す量の名称を出力せよ。
名称が定義されてない場合はundefinedと出力せよ。
また、計算過程で異なる二つの次元の加算もしくは減算するような演算のことを”不正な演算”の定義する。
”不正な演算”があればerrorと出力せよ。
与えられる式は以下を満たす。
すべての変数は組立量の次元に割り当てられている。
式は四則演算+, -, /, *とカッコ（）と変数のみを含む。
四則演算はよく知られているもので、正しく記述されているものとする。厳密には以下のBNFに従う。 また単項演算子は使用されない。(x * (-a))などは存在しない。
<formula>::=<term>|<formula>+<term>|<formula>-<term>
<term>::=<factor>|<term>*<factor>|<term>/<factor>
<factor>::=<variable>|(<formula>)
<variable>::=<string>
<string>::=<char>|<string><char>
<char>::=a~z|A~Z
<formula>が式を表し、<variable>が変数名を表す。
Input
入力は複数のデータセットで構成されている。
データセットの数は1,000個を超えない。
データセットは以下の形式で与えられる。
n m p
derived
1
d
1,1
d
1,2
d
1,3
.... d
1,n
derived
2
d
2,1
d
2,2
d
2,3
.... d
2,n
...
derived
m
d
m,1
d
m,2
d
m,3
.... d
m,n
formula
v
1
D
1
v
2
D
2
...
v
p
D
p
n(1≤n≤5)は基本量の数 m(1≤m≤10) は組立量の数　p(1≤p≤15)は変数の種類数を示す。
derived
i
はi番目の組立量の名前である。アルファベット大文字や小文字から構成され長さは20文字を超えない。
d
i,j
(-10≤d
i,j
≤10)はi番目の組立量のj番目の基本量の次元を表す(1≤i≤m, 1≤j≤n)。
同じ組立量の名称は複数回現れない。
同じ次元の組立量が複数回現れることがあるが、その場合は最後に定義された名称がその組立量の名称となる。
formulaは解析を行う数式を表す。長さは100文字を超えない。
v
i
は変数名を表す。アルファベット大文字や小文字から構成され長さは20文字を超えない。
D
i
はv
i
の次元の名称を表す。すでに与えられた組立量の名称であることが保証されている。
入力中の数（n, m, p, d）はすべて整数である。
入力の終わりは、3個の0がそれぞれ一文字の空白で区切られる一行で示される。
Output
一行に式を解析しその次元の名称を出力せよ。
名称が定義されてない場合はundefinedと出力せよ。
また、不正な演算が含まれる場合はerrorと出力せよ。
Sample Input
2 3 2
length
1 0
time
0 1
speed
1 -1
a/b
a length
b time
2 3 3
length
1 0
time
0 1
speed
1 -1
a/b+c
a length
b time
c speed
2 3 3
length
1 0
time
0 1
speed
1 -1
a/b+c
a length
b time
c time
2 3 2
length
1 0
time
0 1
speed
1 -1
a/b/b
a length
b time
3 6 6
speed
1 -1 0
acceleration
1 -2 0
force
1 -2 1
length
1 0 0
time
0 1 0
weight
0 0 1
((v+l/t)+a*t)/(t*t)*w*t+f+w*a
v speed
l length
a acceleration
t time
w weight
f force
0 0 0
Sample Output
speed
speed
error
undefined
force

Submitted solutions:

code_snippet: #include<map>
#include<cctype>
#include<string>
#include<vector>
#include<iostream>

#define rep(i,n) for(int i=0;i<(n);i++)

using namespace std;

void operator*=(vector<int> &a,const vector<int> &b){ rep(i,a.size()) a[i]+=b[i]; }
void operator/=(vector<int> &a,const vector<int> &b){ rep(i,a.size()) a[i]-=b[i]; }

map< string,vector<int> > f,g; // f : ツ組ツ猟ァツ療環づ個鳴シツ前 -> ツ甘ョツ本ツ療環づ個療ア, g : ツ陛渉青板づ個鳴シツ前 -> ツ甘ョツ本ツ療環づ個療ア
map< vector<int>,string > f_inv;

int idx;
string s;
bool error;

vector<int> expr();

vector<int> variable(){
	string a;
	while(idx<s.length() && isalpha(s[idx])) a+=s[idx++];
	return g[a];
}

vector<int> factor(){
	if(idx<s.length() && s[idx]=='('){
		idx++;
		vector<int> a=expr();
		idx++;
		return a;
	}
	else return variable();
}

vector<int> term(){
	vector<int> a=factor();
	while(idx<s.length() && (s[idx]=='*' || s[idx]=='/')){
		char op=s[idx++];
		vector<int> b=factor();
		if(op=='*') a*=b;
		else        a/=b;
	}
	return a;
}

vector<int> expr(){
	vector<int> a=term();
	while(idx<s.length() && (s[idx]=='+' || s[idx]=='-')){
		idx++;
		vector<int> b=term();
		if(a!=b){ error=true; break; }
	}
	return a;
}

string parse(string formula){
	idx=0;
	s=formula;
	error=false;

	vector<int> res=expr();
	if(error) return "error";
	if(f_inv.count(res)==0) return "undefined";
	return f_inv[res];
}

int main(){
	for(int n,m,p;cin>>n>>m>>p,n;){
		f.clear();
		g.clear();
		f_inv.clear();

		rep(i,m){
			string s; cin>>s;
			vector<int> a(n);
			rep(j,n) cin>>a[j];
			f[s]=a;
			f_inv[a]=s;
		}

		string formula; cin>>formula;
		rep(i,p){
			string s,t; cin>>s>>t;
			g[s]=f[t];
		}

		cout<<parse(formula)<<endl;
	}

	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3204
final_rank: 4

code_snippet: //just test

#include<map>
#include<cctype>
#include<string>
#include<vector>
#include<iostream>

#define rep(i,n) for(int i=0;i<(n);i++)

using namespace std;

void operator*=(vector<int> &a,const vector<int> &b){ rep(i,a.size()) a[i]+=b[i]; }
void operator/=(vector<int> &a,const vector<int> &b){ rep(i,a.size()) a[i]-=b[i]; }

map< string,vector<int> > f,g; // f : ツ組ツ猟ァツ療環づ個鳴シツ前 -> ツ甘ョツ本ツ療環づ個療ア, g : ツ陛渉青板づ個鳴シツ前 -> ツ甘ョツ本ツ療環づ個療ア
map< vector<int>,string > f_inv;

int idx;
string s;
bool error;

vector<int> expr();

vector<int> variable(){
	string a;
	while(idx<s.length() && isalpha(s[idx])) a+=s[idx++];
	return g[a];
}

vector<int> factor(){
	if(idx<s.length() && s[idx]=='('){
		idx++;
		vector<int> a=expr();
		idx++;
		return a;
	}
	else return variable();
}

vector<int> term(){
	vector<int> a=factor();
	while(idx<s.length() && (s[idx]=='*' || s[idx]=='/')){
		char op=s[idx++];
		vector<int> b=factor();
		if(op=='*') a*=b;
		else        a/=b;
	}
	return a;
}

vector<int> expr(){
	vector<int> a=term();
	while(idx<s.length() && (s[idx]=='+' || s[idx]=='-')){
		idx++;
		vector<int> b=term();
		if(a!=b){ error=true; break; }
	}
	return a;
}

string parse(string formula){
	idx=0;
	s=formula;
	error=false;

	vector<int> res=expr();
	if(error) return "error";
	if(f_inv.count(res)==0) return "undefined";
	return f_inv[res];
}

int main(){
	for(int n,m,p;cin>>n>>m>>p,n;){
		f.clear();
		g.clear();
		f_inv.clear();

		rep(i,m){
			string s; cin>>s;
			vector<int> a(n);
			rep(j,n) cin>>a[j];
			f[s]=a;
			f_inv[a]=s;
		}

		string formula; cin>>formula;
		rep(i,p){
			string s,t; cin>>s>>t;
			g[s]=f[t];
		}

		cout<<parse(formula)<<endl;
	}

	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3196
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;

using State = string::const_iterator;
using D = vector<int>;

int n, m, p;
map<string,D> s2d, table;
map<D,string> d2s;
bool error;

D expr(State &itr);
D term(State &itr);
D factor(State &itr);
D variable(State &itr);

void print(D d){
    for(auto x : d){
        cout << x << " ";
    }
    cout << endl;
}

void next_char(State &itr, char expected){
    if(*itr == expected){
        itr++;
    }else{
        // error
        cout << "expected " << expected << " but" << *itr << endl;
        while(*itr){
            cout << *itr;
        }
        cout << endl;
    }
}

D expr(State &itr){
    D res = term(itr);
    while(1){
        if(*itr == '+' || *itr == '-'){
            itr++;
            D tmp = term(itr);
            if(res != tmp){
                error = true;
            }
        }else{
            break;
        }
    }
    return res;
}

D term(State &itr){
    D res = factor(itr);
    while(1){
        if(*itr == '*'){
            next_char(itr, '*');
            D tmp = factor(itr);
            for(int i=0;i<n;i++){
                res[i] += tmp[i];
            }
        }else if(*itr == '/'){
            next_char(itr, '/');
            D tmp = factor(itr);
            for(int i=0;i<n;i++){
                res[i] -= tmp[i];
            }
        }else{
            break;
        }
    }
    return res;
}

D factor(State &itr){
    D res;
    if(*itr == '('){
        next_char(itr, '(');
        res = expr(itr);
        next_char(itr, ')');
    }else{
        res = variable(itr);
    }
    return res;
}

D variable(State &itr){
    string name = "";
    while(isalpha(*itr)){
        name.push_back(*itr);
        itr++;
    }
    if(!name.empty() && table.find(name) != table.end()){
        return table[name];
    }else{
        // error
        cout << "this is not variable" << endl;
        exit(1);
    }
}

int main(){
    while(cin >> n >> m >> p){
        if(n == 0) break;
        s2d.clear();
        d2s.clear();
        table.clear();
        for(int i=0;i<m;i++){
            string derived;
            cin >> derived;
            D d(n);
            for(int j=0;j<n;j++){
                cin >> d[j];
            }
            s2d[derived] = d;
            d2s[d] = derived;
        }
        string formula;
        cin >> formula;

        for(int i=0;i<p;i++){
            string v, d;
            cin >> v >> d;
            table[v] = s2d[d];
        }
        error = false;
        State begin = formula.begin();
        D ans = expr(begin);

        if(error){
            cout << "error" << endl;
        }else if(d2s.find(ans)!=d2s.end()){
            cout << d2s[ans] << endl;
        }else{
            cout << "undefined" << endl;
        }
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3236
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;

using State = string::const_iterator;
using D = vector<int>;

int n, m, p;
map<string,D> s2d, table;
map<D,string> d2s;
bool error;

D expr(State &itr);
D term(State &itr);
D factor(State &itr);
D variable(State &itr);

void print(D d){
    for(auto x : d){
        cout << x << " ";
    }
    cout << endl;
}

void next_char(State &itr, char expected){
    if(*itr == expected){
        itr++;
    }else{
        // error
        cout << "expected " << expected << " but" << *itr << endl;
        while(*itr){
            cout << *itr;
        }
        cout << endl;
    }
}

D expr(State &itr){
    D res = term(itr);
    while(1){
        if(*itr == '+' || *itr == '-'){
            itr++;
            D tmp = term(itr);
            if(res != tmp){
                error = true;
            }
        }else{
            break;
        }
    }
    return res;
}

D term(State &itr){
    D res = factor(itr);
    while(1){
        if(*itr == '*'){
            next_char(itr, '*');
            D tmp = factor(itr);
            for(int i=0;i<n;i++){
                res[i] += tmp[i];
            }
        }else if(*itr == '/'){
            next_char(itr, '/');
            D tmp = factor(itr);
            for(int i=0;i<n;i++){
                res[i] -= tmp[i];
            }
        }else{
            break;
        }
    }
    return res;
}

D factor(State &itr){
    D res;
    if(*itr == '('){
        next_char(itr, '(');
        res = expr(itr);
        next_char(itr, ')');
    }else{
        res = variable(itr);
    }
    return res;
}

D variable(State &itr){
    string name = "";
    while(isalpha(*itr)){
        name.push_back(*itr);
        itr++;
    }
    if(!name.empty() && table.find(name) != table.end()){
        return table[name];
    }else{
        // error
        cout << "this is not variable" << endl;
        exit(1);
    }
}

int main(){
    while(cin >> n >> m >> p){
        if(n == 0) break;
        for(int i=0;i<m;i++){
            string derived;
            cin >> derived;
            D d(n);
            for(int j=0;j<n;j++){
                cin >> d[j];
            }
            s2d[derived] = d;
            d2s[d] = derived;
        }
        string formula;
        cin >> formula;

        for(int i=0;i<p;i++){
            string v, d;
            cin >> v >> d;
            table[v] = s2d[d];
        }
        error = false;
        State begin = formula.begin();
        D ans = expr(begin);

        if(error){
            cout << "error" << endl;
        }else if(d2s.find(ans)!=d2s.end()){
            cout << d2s[ans] << endl;
        }else{
            cout << "undefined" << endl;
        }
    }
    return 0;
}
accuracy: 0.5714285714285714
time_ms: 10
memory_kb: 4364
final_rank: 19

code_snippet: #include <cstdio>
#include <cstdint>
#include <cassert>
#include <cctype>
#include <vector>
#include <string>
#include <map>
#include <algorithm>
#include <stdexcept>

struct Dimension: std::vector<int> {
  Dimension(size_t n=0): std::vector<int>(n) {}
  Dimension &operator +=(const Dimension &oth) {
    if (*this != oth) throw std::logic_error("mismatch");
    return *this;
  }
  Dimension &operator -=(const Dimension &oth) {
    if (*this != oth) throw std::logic_error("mismatch");
    return *this;
  }
  Dimension &operator *=(const Dimension &oth) {
    for (size_t i=0; i<size(); ++i)
      (*this)[i] += oth[i];

    return *this;
  }
  Dimension &operator /=(const Dimension &oth) {
    for (size_t i=0; i<size(); ++i)
      (*this)[i] -= oth[i];

    return *this;
  }
};

Dimension parse(
    const std::string &s, size_t &i,
    const std::map<std::string, Dimension> expr, size_t preced=0) {

  const std::vector<std::string> ops={"+-", "*/"};

  if (preced == ops.size()) {
    if (s[i] == '(') {
      Dimension res=parse(s, ++i, expr, 0);
      assert(s[i] == ')');
      ++i;
      return res;
    }
    if (isalpha(s[i])) {
      std::string name(1, s[i]);
      while (++i < s.length() && isalpha(s[i]))
        name += s[i];

      return expr.at(name);
    }
    assert(false);
  }

  Dimension lhs=parse(s, i, expr, preced+1);
  while (i < s.length()) {
    char op=s[i];
    if (!std::count(ops[preced].begin(), ops[preced].end(), op)) break;
    Dimension rhs=parse(s, ++i, expr, preced+1);
    if (op == '+') lhs += rhs;
    if (op == '-') lhs -= rhs;
    if (op == '*') lhs *= rhs;
    if (op == '/') lhs /= rhs;
  }
  return lhs;
}

int testcase_ends() {
  size_t n, m, p;
  scanf("%zu %zu %zu", &n, &m, &p);
  if (n == 0 && m == 0 && p == 0) return 1;

  std::map<std::string, Dimension> stod;
  std::map<Dimension, std::string> dtos;
  for (size_t i=0; i<m; ++i) {
    char buf[32];
    scanf("%s", buf);
    std::string s=buf;
    Dimension d(n);
    for (size_t j=0; j<n; ++j)
      scanf("%d", &d[j]);

    stod[s] = d;
    dtos[d] = s;
  }

  std::string s;
  {
    char buf[128];
    scanf("%s", buf);
    s = buf;
  }

  std::map<std::string, Dimension> expr;
  for (size_t i=0; i<p; ++i) {
    char buf[128];
    scanf("%s", buf);
    std::string lhs=buf;
    scanf("%s", buf);
    std::string rhs=buf;
    expr[lhs] = stod[rhs];
  }

  size_t i=0;
  try {
    Dimension res=parse(s, i, expr);
    printf("%s\n", dtos.at(res).c_str());
  } catch (std::out_of_range &e) {
    printf("undefined\n");
  } catch (std::logic_error &e) {
    printf("error\n");
  }

  return 0;
}
  
int main() {
  while (!testcase_ends()) {}
}
accuracy: 1
time_ms: 20
memory_kb: 3028
final_rank: 8

code_snippet: #include<bits/stdc++.h>
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;


struct Info{
	char name[21];
	int table[5];
};

struct Data{
	char name[21];
	int info_index;
};

int num_base,num_assembly,num_variable;
char formula[101];
Info info[10];
Data data[15];
bool error_FLG;


bool is_alpha(char ch){

	if(ch >= 'a' && ch <= 'z')return true;
	if(ch >= 'A' && ch <= 'Z')return true;

	return false;
}

//baseとcompが等しいか比べる関数
bool strCmp(char* base, char* comp){
	int length1,length2;
	for(length1=0;base[length1] != '\0';length1++);
	for(length2=0;comp[length2] != '\0';length2++);
	if(length1 != length2)return false;

	for(int i=0;base[i] != '\0'; i++){
		if(base[i] != comp[i])return false;
	}
	return true;
}

void strcpy(char* to,char* str){
	for(int i=0;str[i] != '\0';i++){
		to[i] = str[i];
		to[i+1] = '\0';
	}
}

vector<int> calc_Formula(int,int);

vector<int> calc_string(int left,int right){

	char work[21];
	int index = 0;

	for(int i = left; i <= right; i++){
		work[index++] = formula[i];
	}
	work[index] = '\0';

	vector<int> ret;

	//該当する変数があるか調べる
	for(int i = 0; i < num_variable; i++){
		if(strCmp(work,data[i].name)){
			for(int k = 0; k < num_base; k++){
				ret.push_back(info[data[i].info_index].table[k]);
			}
			return ret;
		}
	}

	//該当する変数がないならエラー
	error_FLG = true;
	return ret;
}

vector<int> calc_variable(int left,int right){
	return calc_string(left,right);
}

vector<int> calc_Factor(int left,int right){

	if(formula[left] == '('){
		return calc_Formula(left+1,right-1);
	}

	return calc_variable(left,right);
}

vector<int> calc_Term(int left,int right){

	int depth = 0;
	queue<int> Q;

	//深さ0の*,/を探す
	for(int i = left; i <= right; i++){

		if(formula[i] == '('){
			depth++;
		}else if(formula[i] == ')'){
			depth--;
		}else if(depth == 0 && (formula[i] == '*' || formula[i] == '/')){
			Q.push(i);
		}
	}

	if(Q.size() == 0){
		return calc_Factor(left,right);
	}

	vector<int> ret,tmp;

	ret = calc_Term(left,Q.front()-1);
	if(error_FLG)return ret;


	while(!Q.empty()){

		int loc = Q.front();
		Q.pop();

		if(Q.empty()){
			tmp = calc_Factor(loc+1,right);
		}else{
			tmp = calc_Factor(loc+1,Q.front()-1);
		}

		if(error_FLG)return ret;

		//次元の計算を行う(指数の加減算)
		if(formula[loc] == '*'){

			for(int i = 0; i < num_base; i++){
				ret[i] += tmp[i];
			}

		}else{ //割り算

			for(int i = 0; i < num_base; i++){

				ret[i] -= tmp[i];
			}
		}
	}

	return ret;

}

vector<int> calc_Formula(int left,int right){

	int depth = 0;
	queue<int> Q;

	//深さ0の+,-を探す
	for(int i = left; i <= right; ){

		if(formula[i] == '('){
			depth++;
		}else if(formula[i] == ')'){
			depth--;
		}

		if(depth != 0){
			i++;
		}else if(formula[i] != '+' && formula[i] != '-'){
			i++;
		}else{
			if(formula[i] == '+'){
				Q.push(i);
				i++;
			}else{ //line[i] == '-'
				if((i != left) && (is_alpha(formula[i-1]) == true || formula[i-1] == ')')){ //-は、depthが0でもnegの場合あり
					Q.push(i);
				}
				while(i <=right && formula[i] == '-')i++; //negの-が続いている場合があるので、読み飛ばす
			}
		}

	}

	if(Q.size() == 0){
		return calc_Term(left,right);
	}

	vector<int> ret,tmp;

	ret = calc_Formula(left,Q.front()-1);
	if(error_FLG)return ret;


	while(!Q.empty()){

		int loc = Q.front();
		Q.pop();

		if(Q.empty()){
			tmp = calc_Term(loc+1,right);
		}else{
			tmp = calc_Term(loc+1,Q.front()-1);
		}

		if(error_FLG)return ret;

		//2つの次元が違うなら終了
		for(int i = 0; i < num_base; i++){
			if(ret[i] != tmp[i]){
				error_FLG = true;
				return ret;
			}
		}
		//★係数は無視するので演算は行わない★
	}

	return ret;
}

void func(){

	//組み立て量の取得
	for(int i = 0; i < num_assembly; i++){

		scanf("%s",info[i].name);
		for(int k = 0; k < num_base; k++){
			scanf("%d",&info[i].table[k]);
		}
	}

	int length;

	scanf("%s",formula);

	for(length = 0; formula[length] != '\0'; length++);

	char buf[21];

	for(int i = 0; i < num_variable; i++){

		scanf("%s %s",data[i].name,buf);
		for(int k = 0; k < num_assembly; k++){ //組み立て量を探す
			if(strCmp(buf,info[k].name)){
				data[i].info_index = k;
				break;
			}
		}
	}

	error_FLG = false;

	vector<int> ret = calc_Formula(0,length-1);

	if(error_FLG){
		printf("error\n");
		return;
	}

	bool FLG;
	//該当する次元があるか探す
	for(int i = num_assembly-1; i >= 0; i--){
		FLG = true;
		for(int k = 0; k < num_base; k++){
			if(ret[k] != info[i].table[k]){
				FLG = false;
				break;
			}
		}
		if(FLG){
			printf("%s\n",info[i].name);
			return;
		}
	}

	printf("undefined\n");
}

int main(){

	while(true){

		scanf("%d %d %d",&num_base,&num_assembly,&num_variable);
		if(num_base == 0 && num_assembly == 0 && num_variable == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3244
final_rank: 10

code_snippet: #include<bits/stdc++.h>
using namespace std;
map<string,vector<int> > sv;
map<vector<int>,string > vs;
map<string,string> ss;
vector<int> dfs();
int n,m,inp,d,p,f;
string s,t,t2;
bool ans;

vector<int> get(){
  vector<int> res(n);
  res[0]=(1e9);
  if(s[p]=='(')p++,res=dfs(),p++;
  else{
    string str;
    while(('a'<=s[p]&&s[p]<='z')||('A'<=s[p]&&s[p]<='Z'))str+=s[p++];
    res=sv[ss[str]];
  }
  return res;
}

vector<int> cal(){
  vector<int> res=get(),r;
  while(s[p]!=')'){
    if(s[p]=='*'){
      p++;
      r=get();
      for(int i=0;i<n;i++)res[i]+=r[i];
    }
    else if(s[p]=='/'){
      p++;
      r=get();
      for(int i=0;i<n;i++)res[i]-=r[i];
    }else break;
  }
  return res;
}

vector<int> dfs(){
  vector<int> res=cal(),r(n);
  r[0]=(1e9);
  while(p<s.size()&&s[p]!=')'){
    if(s[p]=='+'||s[p]=='-')p++;
    else r=cal();
    if(r[0]!=(1e9)&&res!=r)ans=false;
  }
  return res;
}

int main(){
  while(1){
    cin>>n>>m>>inp;
    if(!n&&!m&&!inp)break;
    for(int i=0;i<m;i++){
      cin>>t;
      for(int j=0;j<n;j++){
	cin>>d;
	sv[t].push_back(d);
      }
      vs[sv[t]]=t;
    }
    cin>>s;
    for(int i=0;i<inp;i++){
      cin>>t>>t2;
      ss[t]=t2;
    }
    s='('+s+')'; p=0;
    ans=true;
    vector<int> r=dfs();
    if(!ans)cout<<"error"<<endl;
    else if(vs.count(r))cout<<vs[r]<<endl;
    else cout<<"undefined"<<endl;
    sv.clear();
    vs.clear();
    ss.clear();
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3160
final_rank: 1

code_snippet: #include<bits/stdc++.h>
using namespace std;
map<string,vector<int> > sv;
map<vector<int>,string > vs;
map<string,string> ss;
vector<int> dfs();
int n,m,inp,d,p,f;
string s,t,t2;
bool ans;

vector<int> get(){
  vector<int> res(n);
  res[0]=(1e9);
  if(s[p]=='(')p++,res=dfs(),p++;
  else{
    string str;
    while(('a'<=s[p]&&s[p]<='z')||('A'<=s[p]&&s[p]<='Z'))str+=s[p++];
    res=sv[ss[str]];
  }
  return res;
}

vector<int> cal(){
  vector<int> res=get(),r;
  while(s[p]!=')'){
    if(s[p]=='*'){
      p++;
      r=get();
      for(int i=0;i<n;i++)res[i]+=r[i];
    }
    else if(s[p]=='/'){
      p++;
      r=get();
      for(int i=0;i<n;i++)res[i]-=r[i];
    }else break;
  }
  return res;
}

vector<int> dfs(){
  vector<int> res=cal(),r(n);
  r[0]=(1e9);
  while(p<s.size()&&s[p]!=')'){
    if(s[p]=='('){
      p++;
      r=dfs();
      p++;
    }
    else if(s[p]=='+'||s[p]=='-')p++;
    else r=cal();
    if(r[0]!=(1e9)&&res!=r)ans=false;
  }
  return res;
}

int main(){
  while(1){
    cin>>n>>m>>inp;
    if(!n&&!m&&!inp)break;
    for(int i=0;i<m;i++){
      cin>>t;
      for(int j=0;j<n;j++){
	cin>>d;
	sv[t].push_back(d);
      }
      vs[sv[t]]=t;
    }
    cin>>s;
    for(int i=0;i<inp;i++){
      cin>>t>>t2;
      ss[t]=t2;
    }
    s='('+s+')'; p=0;
    ans=true;
    vector<int> r=dfs();
    if(!ans)cout<<"error"<<endl;
    else if(vs.count(r))cout<<vs[r]<<endl;
    else cout<<"undefined"<<endl;
    sv.clear();
    vs.clear();
    ss.clear();
  }
  return 0;
}
accuracy: 0.5714285714285714
time_ms: 10
memory_kb: 3188
final_rank: 12

code_snippet: #include<bits/stdc++.h>
using namespace std;
map<string,vector<int> > sv;
map<vector<int>,string > vs;
map<string,string> ss;
vector<int> dfs();
int n,m,inp,d,p,f;
string s,t,t2;
bool ans;

vector<int> get(){
  vector<int> res(n);
  res[0]=(1e9);
  if(s[p]=='(')p++,res=dfs(),p++;
  else{
    string str;
    while(('a'<=s[p]&&s[p]<='z')||('A'<=s[p]&&s[p]<='Z'))str+=s[p++];
    res=sv[ss[str]];
  }
  return res;
}

vector<int> cal(){
  vector<int> res=get(),r;
  while(s[p]!=')'){
    if(s[p]=='*'){
      p++;
      r=get();
      for(int i=0;i<n;i++)res[i]+=r[i];
    }
    else if(s[p]=='/'){
      p++;
      r=get();
      for(int i=0;i<n;i++)res[i]-=r[i];
    }else break;
  }
  return res;
}

vector<int> dfs(){
  vector<int> res=cal(),r(n);
  r[0]=(1e9);
  while(p<s.size()&&s[p]!=')'){
    if(s[p]=='('){
      p++;
      r=dfs();
      p++;
    }
    else if(s[p]=='+'||s[p]=='-')p++;
    else r=cal();
    if(res[0]!=(1e9)&&r[0]!=(1e9)&&res!=r)ans=false;
    //if(r[0]!=(1e9))res=r;
  }
  return res;
}

int main(){
  while(1){
    cin>>n>>m>>inp;
    if(!n&&!m&&!inp)break;
    for(int i=0;i<m;i++){
      cin>>t;
      for(int j=0;j<n;j++){
	cin>>d;
	sv[t].push_back(d);
      }
      vs[sv[t]]=t;
    }
    cin>>s;
    for(int i=0;i<inp;i++){
      cin>>t>>t2;
      ss[t]=t2;
    }
    s='('+s+')'; p=0;
    ans=true;
    vector<int> r=dfs();
    if(!ans)cout<<"error"<<endl;
    else if(vs.count(r))cout<<vs[r]<<endl;
    else cout<<"undefined"<<endl;
    sv.clear();
    vs.clear();
    ss.clear();
  }
  return 0;
}
accuracy: 0.5714285714285714
time_ms: 20
memory_kb: 3232
final_rank: 20

code_snippet: #include<bits/stdc++.h>
using namespace std;
map<string,vector<int> > sv;
map<vector<int>,string > vs;
map<string,string> ss;
vector<int> dfs();
int n,m,inp,d,p,f;
string s,t,t2;
bool ans;

vector<int> get(){
  vector<int> res(n);
  res[0]=(1e9);
  if(s[p]=='(')p++,res=dfs(),p++;
  else{
    string str;
    while(('a'<=s[p]&&s[p]<='z')||('A'<=s[p]&&s[p]<='Z'))str+=s[p++];
    res=sv[ss[str]];
  }
  return res;
}

vector<int> cal(){
  vector<int> res=get(),r;
  while(s[p]!=')'){
    if(s[p]=='*'){
      p++;
      r=get();
      for(int i=0;i<n;i++)res[i]+=r[i];
    }
    else if(s[p]=='/'){
      p++;
      r=get();
      for(int i=0;i<n;i++)res[i]-=r[i];
    }else break;
  }
  return res;
}

vector<int> dfs(){
  vector<int> res=cal(),r(n);
  r[0]=(1e9);
  while(p<s.size()&&s[p]!=')'){
    if(s[p]=='('){
      p++;
      r=dfs();
      p++;
    }
    else if(s[p]=='+'||s[p]=='-')p++;
    else r=cal();
    if(res[0]!=(1e9)&&r[0]!=(1e9)&&res!=r)ans=false;
    if(r[0]!=(1e9))res=r;
  }
  return res;
}

int main(){
  while(1){
    cin>>n>>m>>inp;
    if(!n&&!m&&!inp)break;
    for(int i=0;i<m;i++){
      cin>>t;
      for(int j=0;j<n;j++){
	cin>>d;
	sv[t].push_back(d);
      }
      vs[sv[t]]=t;
    }
    cin>>s;
    for(int i=0;i<inp;i++){
      cin>>t>>t2;
      ss[t]=t2;
    }
    s='('+s+')'; p=0;
    ans=true;
    vector<int> r=dfs();
    if(!ans)cout<<"error"<<endl;
    else if(vs.count(r))cout<<vs[r]<<endl;
    else cout<<"undefined"<<endl;
    sv.clear();
    vs.clear();
    ss.clear();
  }
  return 0;
}
accuracy: 0.5714285714285714
time_ms: 10
memory_kb: 3204
final_rank: 13

code_snippet: #include<bits/stdc++.h>
using namespace std;
map<string,vector<int> > sv;
map<vector<int>,string > vs;
map<string,string> ss;
vector<int> dfs();
int n,m,inp,d,p,f;
string s,t,t2;
bool ans;

vector<int> get(){
  vector<int> res(n);
  res[0]=(1e9);
  if(p>=s.size())return res;
  if(s[p]=='(')p++,res=dfs();
  else{
    string str;
    while(('a'<=s[p]&&s[p]<='z')||('A'<=s[p]&&s[p]<='Z'))str+=s[p++];
    res=sv[ss[str]];
  }
  return res;
}

vector<int> cal(){
  vector<int> res=get(),r;
  while(p<s.size()&&s[p]!=')'){
    if(s[p]=='*'){
      p++;
      r=get();
      for(int i=0;i<n;i++)res[i]+=r[i];
    }
    else if(s[p]=='/'){
      p++;
      r=get();
      for(int i=0;i<n;i++)res[i]-=r[i];
    }else break;
  }
  return res;
}

vector<int> dfs(){
  vector<int> res=cal(),r(n);
  r[0]=(1e9);
  while(p<s.size()&&s[p]!=')'){
    if(s[p]=='('){
      p++;
      r=dfs();
      p++;
    }
    else if(s[p]=='+'||s[p]=='-')p++;
    else r=cal();
    if(res[0]!=(1e9)&&r[0]!=(1e9)&&res!=r)ans=false;
    if(r[0]!=(1e9))res=r;
  }
  return res;
}

int main(){
  while(1){
    cin>>n>>m>>inp;
    if(!n&&!m&&!inp)break;
    for(int i=0;i<m;i++){
      cin>>t;
      for(int j=0;j<n;j++){
	cin>>d;
	sv[t].push_back(d);
      }
      vs[sv[t]]=t;
    }
    cin>>s;
    for(int i=0;i<inp;i++){
      cin>>t>>t2;
      ss[t]=t2;
    }
    s='('+s+')'; p=0;
    ans=true;
    vector<int> r=dfs();
    if(!ans)cout<<"error"<<endl;
    else if(vs.count(r))cout<<vs[r]<<endl;
    else cout<<"undefined"<<endl;
    sv.clear();
    vs.clear();
    ss.clear();
  }
  return 0;
}
accuracy: 0.5714285714285714
time_ms: 10
memory_kb: 3228
final_rank: 15

code_snippet: #include<bits/stdc++.h>
using namespace std;
map<string,vector<int> > sv;
map<vector<int>,string > vs;
map<string,string> ss;
vector<int> dfs();
int n,m,inp,d,p,f;
string s,t,t2;
bool ans;

vector<int> get(){
  vector<int> res(n);
  res[0]=(1e9);
  if(s[p]=='(')p++,res=dfs();
  else{
    string str;
    while(('a'<=s[p]&&s[p]<='z')||('A'<=s[p]&&s[p]<='Z'))str+=s[p++];
    res=sv[ss[str]];
  }
  return res;
}

vector<int> cal(){
  vector<int> res=get(),r;
  while(s[p]!=')'){
    if(s[p]=='*'){
      p++;
      r=get();
      for(int i=0;i<n;i++)res[i]+=r[i];
    }
    else if(s[p]=='/'){
      p++;
      r=get();
      for(int i=0;i<n;i++)res[i]-=r[i];
    }else break;
  }
  return res;
}

vector<int> dfs(){
  vector<int> res=cal(),r(n);
  r[0]=(1e9);
  while(p<s.size()&&s[p]!=')'){
    if(s[p]=='('){
      p++;
      r=dfs();
      p++;
    }
    else if(s[p]=='+'||s[p]=='-')p++;
    else r=cal();
    if(res[0]!=(1e9)&&r[0]!=(1e9)&&res!=r)ans=false;
    if(r[0]!=(1e9))res=r;
  }
  return res;
}

int main(){
  while(1){
    cin>>n>>m>>inp;
    if(!n&&!m&&!inp)break;
    for(int i=0;i<m;i++){
      cin>>t;
      for(int j=0;j<n;j++){
	cin>>d;
	sv[t].push_back(d);
      }
      vs[sv[t]]=t;
    }
    cin>>s;
    for(int i=0;i<inp;i++){
      cin>>t>>t2;
      ss[t]=t2;
    }
    s='('+s+')'; p=0;
    ans=true;
    vector<int> r=dfs();
    if(!ans)cout<<"error"<<endl;
    else if(vs.count(r))cout<<vs[r]<<endl;
    else cout<<"undefined"<<endl;
    sv.clear();
    vs.clear();
    ss.clear();
  }
  return 0;
}
accuracy: 0.5714285714285714
time_ms: 10
memory_kb: 3252
final_rank: 18

code_snippet: #include<bits/stdc++.h>
using namespace std;
map<string,vector<int> > sv;
map<vector<int>,string > vs;
map<string,string> ss;
vector<int> dfs();
int n,m,inp,d,p,f;
string s,t,t2;
bool ans;

vector<int> get(){
  vector<int> res(n);
  res[0]=(1e9);
  if(s[p]=='(')p++,res=dfs(),p++;
  else{
    string str;
    while(('a'<=s[p]&&s[p]<='z')||('A'<=s[p]&&s[p]<='Z'))str+=s[p++];
    res=sv[ss[str]];
  }
  return res;
}

vector<int> cal(){
  vector<int> res=get(),r;
  while(p<s.size()&&s[p]!=')'){
    if(s[p]=='*'){
      p++;
      r=get();
      for(int i=0;i<n;i++)res[i]+=r[i];
    }
    else if(s[p]=='/'){
      p++;
      r=get();
      for(int i=0;i<n;i++)res[i]-=r[i];
    }else break;
  }
  return res;
}

vector<int> dfs(){
  vector<int> res=cal(),r(n);
  r[0]=(1e9);
  while(p<s.size()&&s[p]!=')'){
    if(s[p]=='('){
      p++;
      r=dfs();
      p++;
    }
    else if(s[p]=='+'||s[p]=='-')p++;
    else r=cal();
    if(res[0]!=(1e9)&&r[0]!=(1e9)&&res!=r)ans=false;
    if(r[0]!=(1e9))res=r;
  }
  return res;
}

int main(){
  while(1){
    cin>>n>>m>>inp;
    if(!n&&!m&&!inp)break;
    for(int i=0;i<m;i++){
      cin>>t;
      for(int j=0;j<n;j++){
	cin>>d;
	sv[t].push_back(d);
      }
      vs[sv[t]]=t;
    }
    cin>>s;
    for(int i=0;i<inp;i++){
      cin>>t>>t2;
      ss[t]=t2;
    }
    s='('+s+"))"; p=0;
    ans=true;
    vector<int> r=dfs();
    if(!ans)cout<<"error"<<endl;
    else if(vs.count(r))cout<<vs[r]<<endl;
    else cout<<"undefined"<<endl;
    sv.clear();
    vs.clear();
    ss.clear();
  }
  return 0;
}
accuracy: 0.5714285714285714
time_ms: 10
memory_kb: 3076
final_rank: 11

code_snippet: #include<bits/stdc++.h>
using namespace std;
map<string,vector<int> > sv;
map<vector<int>,string > vs;
map<string,string> ss;
vector<int> dfs();
int n,m,inp,d,p,f;
string s,t,t2;
bool ans;

vector<int> get(){
  vector<int> res(n);
  res[0]=(1e9);
  if(s[p]=='(')p++,res=dfs(),p++;
  else{
    string str;
    while(('a'<=s[p]&&s[p]<='z')||('A'<=s[p]&&s[p]<='Z'))str+=s[p++];
    res=sv[ss[str]];
  }
  return res;
}

vector<int> cal(){
  vector<int> res=get(),r;
  while(p<s.size()&&s[p]!=')'){
    if(s[p]=='*'){
      p++;
      r=get();
      for(int i=0;i<n;i++)res[i]+=r[i];
    }
    else if(s[p]=='/'){
      p++;
      r=get();
      for(int i=0;i<n;i++)res[i]-=r[i];
    }else break;
  }
  return res;
}

vector<int> dfs(){
  vector<int> res=cal(),r(n);
  r[0]=(1e9);
  while(p<s.size()&&s[p]!=')'){
    if(s[p]=='('){
      p++;
      r=dfs();
      p++;
    }
    else if(s[p]=='+'||s[p]=='-')p++;
    else r=cal();
    if(res[0]!=(1e9)&&r[0]!=(1e9)&&res!=r)ans=false;
    if(r[0]!=(1e9))res=r;
  }
  return res;
}

int main(){
  while(1){
    cin>>n>>m>>inp;
    if(!n&&!m&&!inp)break;
    for(int i=0;i<m;i++){
      cin>>t;
      for(int j=0;j<n;j++){
	cin>>d;
	sv[t].push_back(d);
      }
      vs[sv[t]]=t;
    }
    cin>>s;
    for(int i=0;i<inp;i++){
      cin>>t>>t2;
      ss[t]=t2;
    }
    s='('+s+')'; p=0;
    ans=true;
    vector<int> r=dfs();
    if(!ans)cout<<"error"<<endl;
    else if(vs.count(r))cout<<vs[r]<<endl;
    else cout<<"undefined"<<endl;
    sv.clear();
    vs.clear();
    ss.clear();
  }
  return 0;
}
accuracy: 0.5714285714285714
time_ms: 10
memory_kb: 3228
final_rank: 15

code_snippet: #include<bits/stdc++.h>
using namespace std;
int N,M,P;
typedef vector<int> vec;
int cnt = 0;
char S[200];
map<string,vec> mp;
map<string,string> mmp;
map<vec,string> vp;
void init(){
  cnt = 0;
  mp.clear(); mmp.clear(); vp.clear();
}
 
bool asset(char c){
  if( S[cnt] == c ) {
    cnt++; return true;
  }
  return false;
}
 
vec variable();
vec factor();
vec term();
vec formula();
vec operator*( const vec& a, const vec& b ) {
  if( a.empty() || b.empty() ) return vec();
  vec x = vec( N );
  for(int i=0;i<N;i++) x[i] = a[i] + b[i];
  return x;
}
vec operator/(const vec& a, const vec& b) {
  if( a.empty() || b.empty() ) return vec();
  vec x = vec( N );
  for(int i=0;i<N;i++) x[i] = a[i] - b[i];
  return x;
}
bool check( const vec &a, const vec &b ){
  if( a.empty() || b.empty() ) return false;
  for(int i=0;i<N;i++)
    if( a[i] != b[i] ) return false;
  return true;
}
vec variable(){
  string s = "";
  while( ( 'a' <= S[cnt] && S[cnt] <= 'z' ) ||
         ( 'A' <= S[cnt] && S[cnt] <= 'Z' ) ){
    s += S[cnt];
    asset( S[cnt] );
  }
  return mp[ mmp[s] ];  
}
vec factor(){
  if( asset( '(' ) ){
    vec v = formula();
    asset(')');
    return v;
  } else
    return variable();
}
vec term(){
  vec v = factor();
  while( true ){
    if( asset( '*' ) ){
      vec nv = factor();
      v = v * nv;
    } else if( asset( '/' ) ){
      vec nv = factor();
      v = v / nv;
    } else
      break;
  }
  return v;
}
vec formula(){
  vec v = term();
  while( true ){
    if( asset( '+' ) ) {}
    else if( asset( '-' ) ){}
    else break;
    vec nv = term();
    if( !check( v, nv ) ) return vec();
  }
  return v;
}
 
int main(){
  while( cin >> N >> M >> P && (N|M|P) ){
    init();
    for(int i=0;i<M;i++){
      string a;
      cin >> a;
      vec v = vec( N );
      for(int j=0;j<N;j++){
        int d; cin >> d;
        v[j] = d;
      }
      mp[a] = v;
      vp[v] = a;
    }
    cin >> S;
    for(int i=0;i<P;i++){
      string a,b; cin >> a >> b;
      mmp[a] = b;
    }
    vec v = formula();
 
 
    if( v.empty() ){
      cout << "error" << endl;
    } else if( vp.count( v ) ){
      cout << vp[v] << endl;
    } else {
      cout << "undefined" << endl;
    }
  }  
}
accuracy: 1
time_ms: 20
memory_kb: 3180
final_rank: 9

code_snippet: #include<bits/stdc++.h>
using namespace std;
int N,M,P;
typedef vector<int> vec;
int cnt = 0;
char S[200];
map<string,vec> mp;
map<string,string> mmp;
map<vec,string> vp;
void init(){
  cnt = 0;
  mp.clear(); mmp.clear(); vp.clear();
}

bool asset(char c){
  if( S[cnt] == c ) {
    cnt++; return true;
  }
  return false;
}

vec variable();
vec factor();
vec term();
vec formula();
vec operator*( const vec& a, const vec& b ) {
  if( a.empty() || b.empty() ) return vec();
  vec x = vec( N );
  for(int i=0;i<N;i++) x[i] = a[i] + b[i];
  return x;
}
vec operator/(const vec& a, const vec& b) {
  if( a.empty() || b.empty() ) return vec();
  vec x = vec( N );
  for(int i=0;i<N;i++) x[i] = a[i] - b[i];
  return x;
}
bool check( const vec &a, const vec &b ){
  if( a.empty() || b.empty() ) return false;
  for(int i=0;i<N;i++)
    if( a[i] != b[i] ) return false;
  return true;
}
vec variable(){
  string s = "";
  while( ( 'a' <= S[cnt] && S[cnt] <= 'z' ) ||
         ( 'A' <= S[cnt] && S[cnt] <= 'Z' ) ){
    s += S[cnt];
    asset( S[cnt] );
  }
  return mp[ mmp[s] ];  
}
vec factor(){
  if( asset( '(' ) ){
    vec v = formula();
    asset(')');
    return v;
  } else
    return variable();
}
vec term(){
  vec v = factor();
  while( true ){
    if( asset( '*' ) ){
      vec nv = factor();
      v = v * nv;
    } else if( asset( '/' ) ){
      vec nv = factor();
      v = v / nv;
    } else
      break;
  }
  return v;
}
vec formula(){
  vec v = term();
  while( true ){
    if( asset( '+' ) ) {}
    else if( asset( '-' ) ){}
    else break;
    vec nv = term();
    if( !check( v, nv ) ) return vec();
  }
  return v;
}

int main(){
  while( cin >> N >> M >> P && (N|M|P) ){
    init();
    for(int i=0;i<M;i++){
      string a;
      cin >> a;
      vec v = vec( N );
      for(int j=0;j<N;j++){
        int d; cin >> d;
        v[j] = d;
      }
      mp[a] = v;
      vp[v] = a;
    }
    cin >> S;
    for(int i=0;i<P;i++){
      string a,b; cin >> a >> b;
      mmp[a] = b;
    }
    vec v = formula();


    if( v.empty() ){
      cout << "error" << endl;
    } else if( vp.count( v ) ){
      cout << vp[v] << endl;
    } else {
      cout << "undefined" << endl;
    }
  }  
}
accuracy: 1
time_ms: 10
memory_kb: 3180
final_rank: 2

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
template<class T>
using Table = vector<vector<T>>;
const ld eps = 1e-9;

//// < "D:\D_Download\Visual Studio 2015\Projects\programing_contest_c++\Debug\a.txt" > "D:\D_Download\Visual Studio 2015\Projects\programing_contest_c++\Debug\b.txt"

string ast;
map<string, vector<int>>avars;
int a;
vector<int>getform();
vector<int>getst() {
	string name;
	while( ('a' <= ast[a] && 'z' >= ast[a]) || ('A' <= ast[a] && 'Z' >= ast[a])){
		name.push_back(ast[a]);
		a++;
	}
	if (avars.find(name) == avars.end()) {
		assert(false);
	}
	else {
		return avars[name];
	}
}
vector<int>getfact() {
	if (ast[a] == '(') {
		a++;
		vector<int>v = getform();
		assert(ast[a] == ')');
		a++;
		return v;
	}
	else {
		return getst();
	}
}
vector<int>getterm() {
	auto v = getfact();
	while (a != ast.size()&&ast[a]!=')') {
		if (ast[a] == '*') {
			a++;
			auto nv = getfact();
			assert(v.size() == nv.size());
			for (int i = 0; i < v.size(); ++i) {
				v[i] += nv[i];
			}
		}
		else if (ast[a] == '/') {
			a++;
			auto nv = getfact();
			assert(v.size() == nv.size());
			for (int i = 0; i < v.size(); ++i) {
				v[i] -= nv[i];
			}
		}
		else if (ast[a] =='+'||ast[a]=='-'){
			break;
		}
		else {
			assert(false);
		}
	}
	return v;
}
vector<int>getform() {
	auto v = getterm();
	while (a!=ast.size() && ast[a] != ')') {
		if (ast[a] == '+'||ast[a]=='-') {
			a++;
			auto nv = getterm();
			if (v == nv) {
				continue;
			}
			else {
				throw(false);
			}
		}
		else {
			assert(false);
		}
	}
	return v;
}

vector<int>getans(const string st,const map<string,vector<int>>&vars) {
	ast = st;
	avars = vars;
	a = 0;
	return getform();
}

int main() {
	while (1) {
		int N, M, P; cin >> N >> M >> P;
		if (!N)break;
		map<string,vector<int>>dim;
		map<vector<int>, string>revdim;
		for (int i = 0; i < M; ++i) {
			string name; cin >> name;
			vector<int>dims(N);
			for (int j = 0; j < N; ++j) {
				cin >> dims[j];
			}
			dim[name] = dims;
			revdim[dims] = name;
		}
		string st; cin >> st;
		map<string,vector<int>>vars;
		for (int i = 0; i < P; ++i) {
			string v; string n; cin >> v >> n;
			vars[v] = dim[n];
		}
		try {
			vector<int>ans = getans(st, vars);
			if (revdim.find(ans) == revdim.end()) {
				cout << "undefined" << endl;
			}
			else {
				cout << revdim[ans] << endl;
			}
		}
		catch (...) {
			cout << "error" << endl;
		}

	}
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3208
final_rank: 5

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
template<class T>
using Table = vector<vector<T>>;
const ld eps = 1e-9;

//// < "D:\D_Download\Visual Studio 2015\Projects\programing_contest_c++\Debug\a.txt" > "D:\D_Download\Visual Studio 2015\Projects\programing_contest_c++\Debug\b.txt"

string ast;
map<string, vector<int>>avars;
int a;
vector<int>getform();
vector<int>getst() {
	string name;
	while( ('a' <= ast[a] && 'z' >= ast[a]) || ('A' <= ast[a] && 'Z' >= ast[a])){
		name.push_back(ast[a]);
		a++;
	}
	if (avars.find(name) == avars.end()) {
		assert(false);
	}
	else {
		return avars[name];
	}
}
vector<int>getfact() {
	if (ast[a] == '(') {
		a++;
		vector<int>v = getform();
		assert(ast[a] == ')');
		a++;
		return v;
	}
	else {
		return getst();
	}
}
vector<int>getterm() {
	auto v = getfact();
	while (a != ast.size()&&ast[a]!=')') {
		if (ast[a] == '*' || ast[a] == '-') {
			a++;
			auto nv = getfact();
			assert(v.size() == nv.size());
			for (int i = 0; i < v.size(); ++i) {
				v[i] += nv[i];
			}
		}
		else if (ast[a] == '/') {
			a++;
			auto nv = getfact();
			assert(v.size() == nv.size());
			for (int i = 0; i < v.size(); ++i) {
				v[i] -= nv[i];
			}
		}
		else if (ast[a] =='+'||ast[a]=='-'){
			break;
		}
		else {
			assert(false);
		}
	}
	return v;
}
vector<int>getform() {
	auto v = getterm();
	while (a!=ast.size() && ast[a] != ')') {
		if (ast[a] == '+'||ast[a]=='-') {
			a++;
			auto nv = getterm();
			if (v == nv) {
				continue;
			}
			else {
				throw(false);
			}
		}
		else {
			assert(false);
		}
	}
	return v;
}

vector<int>getans(const string st,const map<string,vector<int>>&vars) {
	ast = st;
	avars = vars;
	a = 0;
	return getform();
}

int main() {
	while (1) {
		int N, M, P; cin >> N >> M >> P;
		if (!N)break;
		map<string,vector<int>>dim;
		map<vector<int>, string>revdim;
		for (int i = 0; i < M; ++i) {
			string name; cin >> name;
			vector<int>dims(N);
			for (int j = 0; j < N; ++j) {
				cin >> dims[j];
			}
			dim[name] = dims;
			revdim[dims] = name;
		}
		string st; cin >> st;
		map<string,vector<int>>vars;
		for (int i = 0; i < P; ++i) {
			string v; string n; cin >> v >> n;
			vars[v] = dim[n];
		}
		try {
			vector<int>ans = getans(st, vars);
			if (revdim.find(ans) == revdim.end()) {
				cout << "undefined" << endl;
			}
			else {
				cout << revdim[ans] << endl;
			}
		}
		catch (...) {
			cout << "error" << endl;
		}

	}
	return 0;
}
accuracy: 0.5714285714285714
time_ms: 10
memory_kb: 3244
final_rank: 17

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
template<class T>
using Table = vector<vector<T>>;
const ld eps = 1e-9;

//// < "D:\D_Download\Visual Studio 2015\Projects\programing_contest_c++\Debug\a.txt" > "D:\D_Download\Visual Studio 2015\Projects\programing_contest_c++\Debug\b.txt"

string ast;
map<string, vector<int>>avars;
int a;
vector<int>getform();
vector<int>getst() {
	string name;
	while( ('a' <= ast[a] && 'z' >= ast[a]) || ('A' <= ast[a] && 'Z' >= ast[a])){
		name.push_back(ast[a]);
		a++;
	}
	if (avars.find(name) == avars.end()) {
		assert(false);
	}
	else {
		return avars[name];
	}
}
vector<int>getfact() {
	if (ast[a] == '(') {
		a++;
		vector<int>v = getform();
		a++;
		return v;
	}
	else {
		return getst();
	}
}
vector<int>getterm() {
	auto v = getfact();
	while (a != ast.size()&&ast[a]!=')') {
		if (ast[a] == '*' || ast[a] == '-') {
			a++;
			auto nv = getfact();
			for (int i = 0; i < v.size(); ++i) {
				v[i] += nv[i];
			}
		}
		else if (ast[a] == '/') {
			a++;
			auto nv = getfact();
			for (int i = 0; i < v.size(); ++i) {
				v[i] -= nv[i];
			}
		}
		else if (ast[a] =='+'||ast[a]=='-'){
			break;
		}
		else {
			assert(false);
		}
	}
	return v;
}
vector<int>getform() {
	auto v = getterm();
	while (a!=ast.size() && ast[a] != ')') {
		if (ast[a] == '+'||ast[a]=='-') {
			a++;
			auto nv = getterm();
			if (v == nv) {
				continue;
			}
			else {
				throw(false);
			}
		}
		else {
			assert(false);
		}
	}
	return v;
}

vector<int>getans(const string st,const map<string,vector<int>>&vars) {
	ast = st;
	avars = vars;
	a = 0;
	return getform();
}

int main() {
	while (1) {
		int N, M, P; cin >> N >> M >> P;
		if (!N)break;
		map<string,vector<int>>dim;
		map<vector<int>, string>revdim;
		for (int i = 0; i < M; ++i) {
			string name; cin >> name;
			vector<int>dims(N);
			for (int j = 0; j < N; ++j) {
				cin >> dims[j];
			}
			dim[name] = dims;
			revdim[dims] = name;
		}
		string st; cin >> st;
		map<string,vector<int>>vars;
		for (int i = 0; i < P; ++i) {
			string v; string n; cin >> v >> n;
			vars[v] = dim[n];
		}
		try {
			vector<int>ans = getans(st, vars);
			if (revdim.find(ans) == revdim.end()) {
				cout << "undefined" << endl;
			}
			else {
				cout << revdim[ans] << endl;
			}
		}
		catch (...) {
			cout << "error" << endl;
		}

	}
	return 0;
}
accuracy: 0.5714285714285714
time_ms: 10
memory_kb: 3216
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define dump(...) cout<<"# "<<#__VA_ARGS__<<'='<<(__VA_ARGS__)<<endl
#define repi(i,a,b) for(int i=int(a);i<int(b);i++)
#define peri(i,a,b) for(int i=int(b);i-->int(a);)
#define rep(i,n) repi(i,0,n)
#define per(i,n) peri(i,0,n)
#define all(c) begin(c),end(c)
#define mp make_pair
#define mt make_tuple

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;

template<typename T1,typename T2>
ostream& operator<<(ostream& os,const pair<T1,T2>& p){
	return os<<'('<<p.first<<','<<p.second<<')';
}

template<typename Tuple>
void print_tuple(ostream&,const Tuple&){}
template<typename Car,typename... Cdr,typename Tuple>
void print_tuple(ostream& os,const Tuple& t){
	print_tuple<Cdr...>(os,t);
	os<<(sizeof...(Cdr)?",":"")<<get<sizeof...(Cdr)>(t);
}
template<typename... Args>
ostream& operator<<(ostream& os,const tuple<Args...>& t){
	print_tuple<Args...>(os<<'(',t);
	return os<<')';
}

template<typename Ch,typename Tr,typename C,typename=decltype(begin(C()))>
basic_ostream<Ch,Tr>& operator<<(basic_ostream<Ch,Tr>& os,const C& c){
	os<<'[';
	for(auto i=begin(c);i!=end(c);++i)
		os<<(i==begin(c)?"":" ")<<*i;
	return os<<']';
}

constexpr int INF=1e9;
constexpr int MOD=1e9+7;
constexpr double EPS=1e-9;

tuple<vi,int> expr(const string& s,int i,const map<string,vi>& utod,const map<string,string>& vtou);
	
tuple<vi,int> fact(const string& s,int i,const map<string,vi>& utod,const map<string,string>& vtou)
{
	if(s[i]=='('){
		vi ds; tie(ds,i)=expr(s,i+1,utod,vtou);
		return mt(ds,i+1);
	}
	else{
		string var;
		for(;i<s.size() && isalpha(s[i]);i++)
			var+=s[i];
		return mt(utod.at(vtou.at(var)),i);
	}
}
tuple<vi,int> term(const string& s,int i,const map<string,vi>& utod,const map<string,string>& vtou)
{
	vi ds; tie(ds,i)=fact(s,i,utod,vtou);
	while(i<s.size() && (s[i]=='*' || s[i]=='/')){
		//dump(mt(__func__,i,s[i]));
		assert(s[i]=='*' || s[i]=='/');
		char op=s[i];
		vi ds2; tie(ds2,i)=fact(s,i+1,utod,vtou);
		if(op=='*')
			rep(j,ds.size()) ds[j]+=ds2[j];
		else
			rep(j,ds.size()) ds[j]-=ds2[j];
	}
	return mt(ds,i);
}
tuple<vi,int> expr(const string& s,int i,const map<string,vi>& utod,const map<string,string>& vtou)
{
	vi ds; tie(ds,i)=term(s,i,utod,vtou);
	while(i<s.size() && s[i]!=')'){
		//dump(mt(__func__,i,s[i]));
		assert(s[i]=='+' || s[i]=='-');
		vi ds2; tie(ds2,i)=term(s,i+1,utod,vtou);
		if(ds!=ds2) throw "error";
	}
	return mt(ds,i);
}

int main()
{
	for(int n,m,p;cin>>n>>m>>p && n|m|p;){
		map<string,vi> utod; // unit -> dimension
		rep(i,m){
			string unit; cin>>unit;
			vi ds(n);
			rep(j,n) cin>>ds[j];
			utod[unit]=ds;
		}
		string s; cin>>s;
		map<string,string> vtou; // variable -> unit
		rep(i,p){
			string var,unit; cin>>var>>unit;
			vtou[var]=unit;
		}
		//dump(mt(n,m,p)); dump(s); dump(utod); dump(vtou);
		
		try{
			vi ds; tie(ds,ignore)=expr(s,0,utod,vtou);
			string res="undefined";
			for(auto p:utod)
				if(ds==p.second)
					res=p.first;
			cout<<res<<endl;
		}
		catch(const char* msg){
			cout<<msg<<endl;
		}
	}
}
accuracy: 1
time_ms: 20
memory_kb: 1308
final_rank: 7