Problem:
Problem A:
Hit and Blow
Hit and blow
is a popular code-breaking game played by two people, one codemaker and one
codebreaker. The objective of this game is that the codebreaker guesses correctly a secret
number the codemaker makes in his or her mind.
The game is played as follows. The codemaker first chooses a secret number that consists of
four different digits, which may contain a leading zero. Next, the codebreaker makes the first
attempt to guess the secret number. The guessed number needs to be legal (i.e. consist of four
different digits). The codemaker then tells the numbers of
hits
and
blows
to the codebreaker.
Hits are the matching digits on their right positions, and blows are those on different positions.
For example, if the secret number is 4321 and the guessed is 2401, there is one hit and two blows
where 1 is a hit and 2 and 4 are blows. After being told, the codebreaker makes the second
attempt, then the codemaker tells the numbers of hits and blows, then the codebreaker makes
the third attempt, and so forth. The game ends when the codebreaker gives the correct number.
Your task in this problem is to write a program that determines, given the situation, whether
the codebreaker can logically guess the secret number within the next two attempts. Your
program will be given the four-digit numbers the codebreaker has guessed, and the responses
the codemaker has made to those numbers, and then should make output according to the
following rules:
if only one secret number is possible, print the secret number;
if more than one secret number is possible, but there are one or more critical numbers,
      print the
smallest
one;
otherwise, print “????” (four question symbols).
Here, critical numbers mean those such that, after being given the number of hits and blows for
them on the next attempt, the codebreaker can determine the secret number uniquely.
Input
The input consists of multiple data sets. Each data set is given in the following format:
N
four-digit-number
1
n-hits
1
n-blows
1
...
four-digit-number
N
n-hits
N
n-blows
N
N
is the number of attempts that has been made.
four-digit-number
i
is the four-digit number
guessed on the
i
-th attempt, and
n-hits
i
and
n-blows
i
are the numbers of hits and blows for that
number, respectively. It is guaranteed that there is at least one possible secret number in each
data set.
The end of input is indicated by a line that contains a zero. This line should not be processed.
Output
For each data set, print a four-digit number or “????” on a line, according to the rules stated
above.
Sample Input
2
1234 3 0
1245 3 0
1
1234 0 0
2
0123 0 4
1230 0 4
0
Output for the Sample Input
1235
????
0132

Submitted solutions:

code_snippet: #include "bits/stdc++.h"
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/tag_and_trait.hpp>
using namespace __gnu_pbds;
using namespace std;
using ll = long long;
using ld = long double;
using ull = unsigned long long;
#define rep(i, m, n) for (ll i = (ll)m; i < (ll)n; i++)
#define drep(i, m, n) for (ll i = m - 1; i >= n; i--)
#define Endl endl
#define all(a) a.begin(), a.end()
#define pr(i, j) make_pair(i, j)
#define isin(x, l, r) (l <= x && x < r)
#define chmin(a, b) a = min(a, b)
#define chmax(a, b) a = max(a, b)
#define srt(ar) sort(ar.begin(), ar.end())
#define rev(ar) reverse(ar.begin(), ar.end())
#define jge(f, s, t) cout << (f ? s : t) << endl
template <typename T>
using ordered_set = tree<T, null_type, std::less<T>, rb_tree_tag, tree_order_statistics_node_update>;
#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

#define printar(ar)             \
    do                          \
    {                           \
        for (auto dbg : ar)     \
        {                       \
            cout << dbg << " "; \
        }                       \
        cout << endl;           \
    } while (0)
const ll inf = 1e18;
const ld pi = 3.14159265358979;
const ld eps = 1e-9;
template <class T, ll n, ll idx = 0>
auto make_vec(const ll (&d)[n], const T &init) noexcept
{
    if constexpr (idx < n)
        return std::vector(d[idx], make_vec<T, n, idx + 1>(d, init));
    else
        return init;
}

template <class T, ll n>
auto make_vec(const ll (&d)[n]) noexcept
{
    return make_vec(d, T{});
}
//////////////// 以下を貼る ////////////////
template <class T>
size_t HashCombine(const size_t seed, const T &v)
{
    return seed ^ (std::hash<T>()(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2));
}
/* pair用 */
template <class T, class S>
struct std::hash<std::pair<T, S>>
{
    size_t operator()(const std::pair<T, S> &keyval) const noexcept
    {
        return HashCombine(std::hash<T>()(keyval.first), keyval.second);
    }
};
/* vector用 */
template <class T>
struct std::hash<std::vector<T>>
{
    size_t operator()(const std::vector<T> &keyval) const noexcept
    {
        size_t s = 0;
        for (auto &&v : keyval)
            s = HashCombine(s, v);
        return s;
    }
};
/* tuple用 */
template <int N>
struct HashTupleCore
{
    template <class Tuple>
    size_t operator()(const Tuple &keyval) const noexcept
    {
        size_t s = HashTupleCore<N - 1>()(keyval);
        return HashCombine(s, std::get<N - 1>(keyval));
    }
};
template <>
struct HashTupleCore<0>
{
    template <class Tuple>
    size_t operator()(const Tuple &keyval) const noexcept { return 0; }
};
template <class... Args>
struct std::hash<std::tuple<Args...>>
{
    size_t operator()(const tuple<Args...> &keyval) const noexcept
    {
        return HashTupleCore<tuple_size<tuple<Args...>>::value>()(keyval);
    }
};
////////////////////////////////////////////
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    while (true)
    {
        ll n;
        cin >> n;
        if (n == 0)
        {
            break;
        }
        vector<string> s(n);
        vector<ll> h(n);
        vector<ll> b(n);
        rep(i, 0, n)
        {
            cin >> s[i] >> h[i] >> b[i];
        }
        vector<string> ar;
        rep(i, 100, 10000)
        {
            string t = to_string(i);
            while (t.length() < 4)
            {
                t = "0" + t;
            }
            set<char> st;
            rep(i, 0, 4)
            {
                st.insert(t[i]);
            }
            if (st.size() != 4)
            {
                continue;
            }
            bool f = true;
            rep(j, 0, n)
            {
                ll H = 0, B = 0;
                rep(k, 0, 4)
                {
                    if (s[j][k] == t[k])
                    {
                        H++;
                    }
                    rep(l, 0, 4)
                    {
                        if (s[j][l] == t[k])
                        {
                            B++;
                        }
                    }
                }
                B -= H;
                if (b[j] != B || h[j] != H)
                {
                    f = false;
                }
            }
            if (f)
            {
                ar.push_back(t);
            }
        }
        if (ar.size() == 1)
        {
            cout << ar[0] << endl;
            continue;
        }
        bool g = false;
        rep(i, 100, 10000)
        {
            string t = to_string(i);
            while (t.length() < 4)
            {
                t = "0" + t;
            }
            set<char> st;
            rep(i, 0, 4)
            {
                st.insert(t[i]);
            }
            if (st.size() != 4)
            {
                continue;
            }
            set<pair<ll, ll>> st2;
            rep(j, 0, ar.size())
            {
                ll H = 0, B = 0;
                rep(k, 0, 4)
                {
                    if (ar[j][k] == t[k])
                    {
                        H++;
                    }
                    rep(l, 0, 4)
                    {
                        if (ar[j][l] == t[k])
                        {
                            B++;
                        }
                    }
                }
                B -= H;
                st2.insert(pr(H, B));
            }
            if (st2.size() == ar.size())
            {
                cout << t << endl;
                g = true;
                break;
            }
        }
        if (!g)
        {
            cout << "????" << endl;
        }
    }
}
accuracy: 1
time_ms: 640
memory_kb: 3584
final_rank: 18

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.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{
	int hit,blow;
};

struct Data{
	int number,hit,blow;
};

int N;
int table[5040];
Data data[5040];

Info calc(int left,int right){

	Info ret;

	int table_left[10],table_right[10];

	for(int i = 0; i < 10; i++){
		table_left[i] = -1;
		table_right[i] = -1;
	}

	int S = 10;
	for(int i = 1; i <= 4; i++){
		table_left[left%S] = i;
		left /= S;
		table_right[right%S] = i;
		right /= S;
	}

	ret.hit = 0;
	ret.blow = 0;

	for(int i = 0; i < 10; i++){
		if(table_left[i] != -1){
			if(table_left[i] == table_right[i]){
				ret.hit++;
			}else if(table_right[i] != -1){
				ret.blow++;
			}
		}
	}

	return ret;
}

void func(){

	for(int i = 0; i < N; i++){
		scanf("%d %d %d",&data[i].number,&data[i].hit,&data[i].blow);
	}

	vector<int> CANDIDATE;
	bool FLG;
	Info ret;

	for(int i = 0; i < 5040; i++){
		FLG = true;
		for(int k = 0; k < N; k++){
			ret = calc(data[k].number,table[i]);
			if(ret.hit != data[k].hit || ret.blow != data[k].blow){
				FLG = false;
				break;
			}
		}
		if(FLG){
			CANDIDATE.push_back(i);
		}
	}

	if(CANDIDATE.size() == 1){
		if(table[CANDIDATE[0]] < 1000){
			printf("0");
		}
		printf("%d\n",table[CANDIDATE[0]]);
		return;
	}

	vector<int> WORK;
	int tmp_number,hit_blow;

	for(int i = 0; i < 5040; i++){
		tmp_number = table[i];
		WORK.clear();

		FLG = true;
		for(int k = 0; k < CANDIDATE.size(); k++){
			if(tmp_number == CANDIDATE[k])continue;

			ret = calc(tmp_number,table[CANDIDATE[k]]);
			hit_blow = 10000*ret.hit+ret.blow;

			for(int a = 0; a < WORK.size(); a++){
				if(WORK[a] == hit_blow){
					FLG = false;
					break;
				}
			}
			if(!FLG)break;
			else{
				WORK.push_back(hit_blow);
			}
		}
		if(FLG){
			if(tmp_number < 1000){
				printf("0");
			}
			printf("%d\n",tmp_number);
			return;
		}
	}

	printf("????\n");
}

int main(){

	int index = 0;

	for(int a = 0; a <= 9; a++){
		for(int b = 0; b <= 9; b++){
			for(int c = 0; c <= 9; c++){
				for(int d = 0; d <= 9; d++){
					if(a != b && a != c && a != d && b != c && b != d && c != d){
						table[index] = 1000*a+100*b+10*c+d;
						index++;
					}
				}
			}
		}
	}

	while(true){
		scanf("%d",&N);
		if(N == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3184
final_rank: 17

code_snippet: #include<stdio.h>
#include<algorithm>
using namespace std;
char str[1100][6];
char t[6];
char w[6];
int p[1100];
int q[1100];
int h[11000];
int u[5][5];
int A[5];
int B[5];
int main(){
	int a;
	while(scanf("%d",&a),a){
		for(int i=0;i<a;i++){
			scanf("%s%d%d",str[i],p+i,q+i);
		}
		int sz=0;
		for(int i=0;i<10000;i++){
			bool ok=true;
			sprintf(t,"%04d",i);
			for(int j=0;j<4;j++)for(int k=j+1;k<4;k++)
				if(t[j]==t[k])ok=false;
			for(int j=0;j<a;j++){
				for(int k=0;k<4;k++)A[k]=B[k]=0;
				int H=0;int L=0;
				for(int k=0;k<4;k++)if(t[k]==str[j][k]){H++;A[k]=B[k]=1;}
				for(int k=0;k<4;k++){
					if(A[k])continue;
					for(int l=0;l<4;l++){
						if(B[l])continue;
						if(t[k]==str[j][l]){L++;A[k]=B[l]=1;break;}
					}
				}
				if(H!=p[j]||L!=q[j]){ok=false;break;}
			}
			if(ok)h[sz++]=i;
		}
	//	printf("%d\n",sz);
		if(sz==1){
			printf("%04d\n",h[0]);
		}else if(sz>25){
			printf("????\n");
		}else{
			bool yet=true;
			for(int i=0;i<10000;i++){
				for(int j=0;j<5;j++)for(int k=0;k<5;k++)u[j][k]=0;
				sprintf(t,"%04d",i);
				bool dame=false;
				for(int j=0;j<4;j++)for(int k=j+1;k<4;k++)
					if(t[j]==t[k])dame=true;
				if(dame)continue;
				for(int j=0;j<sz;j++){
					sprintf(w,"%04d",h[j]);
					for(int k=0;k<4;k++)A[k]=B[k]=0;
					int	H=0;int L=0;
					for(int k=0;k<4;k++)if(t[k]==w[k]){H++;A[k]=B[k]=1;}
					for(int k=0;k<4;k++){
						if(A[k])continue;
						for(int l=0;l<4;l++){
							if(B[l])continue;
							if(t[k]==w[l]){L++;A[k]=B[l]=1;break;}
						}
					}
			//		printf("%d %s: %d %d\n",h[j],str[h[j]],H,L);
					u[H][L]++;
				}
				bool ok=true;
				for(int j=0;j<5;j++)for(int k=0;k<5;k++)
					if(u[j][k]>=2)ok=false;
				if(ok){yet=false;printf("%04d\n",i);break;}
			}
			if(yet)printf("????\n");
		}
	}
}
accuracy: 1
time_ms: 170
memory_kb: 1072
final_rank: 6

code_snippet: #include<iostream>
using namespace std;
int n,t[4];
int num[10000],h[10000],b[10000];
int ans[1000][4],ans_cnt;
int u[4];
int hcnt,bcnt;
int used[10];
void check(){
  //if(t[0]==0&&t[1]==1&&t[2]==3&&t[3]==2)cout<<'A'<<endl;
  int i;
  for(i=0;i<n;i++){
    u[3]=num[i]%10;
    u[2]=(num[i]/10)%10;
    u[1]=(num[i]/100)%10;
    u[0]=num[i]/1000;
 
    hcnt=bcnt=0;
 
    for(int j=0;j<4;j++){
      if(t[j]==u[j])hcnt++;
      else{
    for(int k=0;k<4;k++){
      if(t[j]==u[k]){
        bcnt++;
        break;
      }
    }
      }
    }
    if(!(hcnt==h[i]&&bcnt==b[i]))break;
  }
  if(i==n){
     
    for(int j=0;j<4;j++){
      ans[ans_cnt][j]=t[j];
       
    }
    ans_cnt++;
 
  }
 
}
 
void compute(int x){
  //cout<<x<<'A'<<endl;
  if(x==4)check();
  else{
    for(int i=0;i<10;i++){
      if(used[i]==1)continue;
      used[i]=1;
      t[x]=i;
      compute(x+1);
      used[i]=0;
    }
  }
}
 
int FLG;
int flg[5][5],v[4];
void check2(){
  // cout<<t[0]<<t[1]<<t[2]<<t[3]<<endl;
  for(int i=0;i<5;i++)for(int j=0;j<5;j++)flg[i][j]=0;
  for(int i=0;i<ans_cnt;i++){
    hcnt=bcnt=0;
    for(int j=0;j<4;j++){
      if(t[j]==ans[i][j])hcnt++;
      else{
    for(int k=0;k<4;k++){
      if(t[j]==ans[i][k]){
        bcnt++;
        break;
      }
    }
      }
    }
    if(flg[hcnt][bcnt]==1)return;
    else flg[hcnt][bcnt]=1;
  }
  if(FLG==0){
    for(int i=0;i<4;i++)v[i]=t[i];
    FLG=1;
  }
}
 
void compute2(int x){
  //cout<<x<<'A'<<endl;
  if(x==4)check2();
  else{
    for(int i=0;i<10;i++){
      if(used[i]==1)continue;
      used[i]=1;
      t[x]=i;
      compute2(x+1);
      used[i]=0;
    }
  }
}
 
int main(){
  while(cin>>n&&n){
    for(int i=0;i<n;i++)cin>>num[i]>>h[i]>>b[i];
    for(int i=0;i<10;i++)used[i]=0;
    ans_cnt=0;
    compute(0);
    if(ans_cnt==1){
      cout<<ans[0][0]<<ans[0][1]<<ans[0][2]<<ans[0][3]<<endl;
      continue;
    }
    for(int i=0;i<10;i++)used[i]=0;
    FLG=0;
    compute2(0);
     
    if(FLG==0)cout<<"????"<<endl;
    else cout<<v[0]<<v[1]<<v[2]<<v[3]<<endl;
     
  }
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 1192
final_rank: 8

code_snippet: #include<bits/stdc++.h>

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define IINF (INT_MAX)

using namespace std;

typedef pair<int,int> ii;

struct Data{
  int number,hit,blow;
  Data(int number=IINF,int hit=IINF,int blow=IINF):number(number),hit(hit),blow(blow){}
};

int N;
int divi[] = {1,10,100,1000};

vector<int> compute(vector<Data> info){
  vector<int> res;
  rep(fir,10){
    rep(sec,10){
      if( fir == sec ) continue;
      rep(thr,10){
	if( thr == fir || thr == sec ) continue;
	rep(fou,10){
	  if( fir == fou || sec == fou || thr == fou ) continue;
	  int number = fir * 1000 + sec * 100 + thr * 10 + fou;
	  bool check = true;
	  rep(i,info.size()){
	    int hit = 0, blow = 0;
	    bool exist[10];
	    rep(k,10)exist[k] = false;
	    exist[fir] = exist[sec] = exist[thr] = exist[fou] = true;
	    rep(j,4){
	      int digit_1 = floor(number / divi[j]), digit_2 = floor(info[i].number / divi[j]);
	      digit_1 %= 10, digit_2 %= 10;
	      if( digit_1 == digit_2 )  hit++;
	      else if( exist[digit_2] ) blow++;
	    }
	    if( !( hit == info[i].hit && blow == info[i].blow ) ) {
	      check = false;
	      break;
	    }
	  }
	  if( check ){
	    res.push_back(number);
	  }
	}
      }
    }
  }
  return res;
}

bool computer(vector<int> vec){
  int len = vec.size();
  rep(fir,10){
    rep(sec,10){
      if( sec == fir ) continue;
      rep(thr,10){
	if( thr == fir || thr == sec ) continue;
	rep(fou,10){
	  if( fou == fir || fou == sec || fou == thr ) continue;
	  set<ii> checker;
	  int number = fir * 1000 + sec * 100 + thr * 10 + fou;
	  rep(i,len){
	    ii score = ii(0,0);
	    bool exist[10];
	    rep(j,10)exist[j] = false;

	    rep(j,4){
	      int digit_2 = floor( vec[i] / divi[j] );
	      digit_2 %= 10;
	      exist[digit_2] = true;
	    }

	    rep(j,4){
	      int digit_1 = floor( number / divi[j] ), digit_2 = floor( vec[i] / divi[j] );
	      digit_1 %= 10, digit_2 %= 10;
	      if( digit_1 == digit_2 ) score.first++;
	      else if( exist[digit_1] ) score.second++;
	    }

	    checker.insert(score);

	  }
	  if( (int)checker.size() == len ){
	    printf("%d%d%d%d\n",fir,sec,thr,fou);
	    return true;
	  }
	}
      }
    }
  }
  return false;
}

int main(){
  while(cin>>N,N){
    vector<Data> info(N);
    rep(i,N)cin >> info[i].number >> info[i].hit >> info[i].blow;
    vector<int> tmp = compute(info);
    if( tmp.size() == 1 ){
      cout << string(4-(int)(log10(tmp[0])+1),'0') << tmp[0] << endl;
      continue;
    }
    if( tmp.empty()){
      puts("????");
      continue;
    }
    if(!computer(tmp))cout << string(4,'?') << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 4480
memory_kb: 1312
final_rank: 19

code_snippet: #include<iostream>
using namespace std;
int n,t[4];
int num[10000],h[10000],b[10000];
int ans[1000][4],ans_cnt;
int u[4];
int hcnt,bcnt;
int used[10];
void check(){
  //if(t[0]==0&&t[1]==1&&t[2]==3&&t[3]==2)cout<<'A'<<endl;
  int i;
  for(i=0;i<n;i++){
    u[3]=num[i]%10;
    u[2]=(num[i]/10)%10;
    u[1]=(num[i]/100)%10;
    u[0]=num[i]/1000;

    hcnt=bcnt=0;

    for(int j=0;j<4;j++){
      if(t[j]==u[j])hcnt++;
      else{
	for(int k=0;k<4;k++){
	  if(t[j]==u[k]){
	    bcnt++;
	    break;
	  }
	}
      }
    }
    if(!(hcnt==h[i]&&bcnt==b[i]))break;
  }
  if(i==n){
    
    for(int j=0;j<4;j++){
      ans[ans_cnt][j]=t[j];
      
    }
    ans_cnt++;

  }

}

void compute(int x){
  //cout<<x<<'A'<<endl;
  if(x==4)check();
  else{
    for(int i=0;i<10;i++){
      if(used[i]==1)continue;
      used[i]=1;
      t[x]=i;
      compute(x+1);
      used[i]=0;
    }
  }
}

int FLG;
int flg[5][5],v[4];
void check2(){
  // cout<<t[0]<<t[1]<<t[2]<<t[3]<<endl;
  for(int i=0;i<5;i++)for(int j=0;j<5;j++)flg[i][j]=0;
  for(int i=0;i<ans_cnt;i++){
    hcnt=bcnt=0;
    for(int j=0;j<4;j++){
      if(t[j]==ans[i][j])hcnt++;
      else{
	for(int k=0;k<4;k++){
	  if(t[j]==ans[i][k]){
	    bcnt++;
	    break;
	  }
	}
      }
    }
    if(flg[hcnt][bcnt]==1)return;
    else flg[hcnt][bcnt]=1;
  }
  if(FLG==0){
    for(int i=0;i<4;i++)v[i]=t[i];
    FLG=1;
  }
}

void compute2(int x){
  //cout<<x<<'A'<<endl;
  if(x==4)check2();
  else{
    for(int i=0;i<10;i++){
      if(used[i]==1)continue;
      used[i]=1;
      t[x]=i;
      compute2(x+1);
      used[i]=0;
    }
  }
}

int main(){
  while(cin>>n&&n){
    for(int i=0;i<n;i++)cin>>num[i]>>h[i]>>b[i];
    for(int i=0;i<10;i++)used[i]=0;
    ans_cnt=0;
    compute(0);
    if(ans_cnt==1){
      cout<<ans[0][0]<<ans[0][1]<<ans[0][2]<<ans[0][3]<<endl;
      continue;
    }
    for(int i=0;i<10;i++)used[i]=0;
    FLG=0;
    compute2(0);
    
    if(FLG==0)cout<<"????"<<endl;
    else cout<<v[0]<<v[1]<<v[2]<<v[3]<<endl;
    
  }
  return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 1192
final_rank: 9

code_snippet: #include<iostream>
#include<vector>
#include<algorithm>
#include<set>
#include<cassert>
#include<cstring>

using namespace std;

bool can[5][10];

typedef pair<int,int> P;

struct Info{
  string s;
  int hit, blow;
};

P getHit_Blow(const string& a, const string& b){
  P res(0,0);
  for(int i = 0; i < (int)a.length(); i++) if(a[i] == b[i]) res.first++;

  for(int i = 0; i < (int)a.length(); i++)
    for(int j = 0; j < (int)b.length(); j++) if(a[i] == b[j]) res.second++;

  res.second -= res.first;
  //  if(res.first == 3 && res.second == 1) cout << a << " " << b << endl;
  assert(res.first >= 0 && res.second >= 0);
  return res;
}

bool isValid(const string& s, const vector<Info>& v){
    for(int i = 0; i < (int)v.size(); i++){
    P p = getHit_Blow(v[i].s, s);
    if(p.first != v[i].hit || p.second != v[i].blow) return false;
  }
  return true;
}

string findCritical(const vector<string>& v, const vector<string>& possible){
  
  for(int i = 0; i < (int)possible.size(); i++){
    set<P> s;
    for(int j = 0; j < (int)v.size(); j++){
      P p = getHit_Blow(possible[i], v[j]);
      if(s.find(p) != s.end()) break;
      s.insert(p);
    }
    if(s.size() == v.size()) return possible[i];
  }
  return "????";
}

void generate(vector<string>& possible){
  possible.clear();

  for(int i = 0; i < 10; i++){
    for(int j = 0; j < 10; j++){
      if(i == j) continue;
      for(int k = 0; k < 10; k++){
	if(i == k || j == k) continue;
	for(int l = 0; l < 10; l++){
	  if(i == l || j == l || k == l) continue;
	  string s = "????";
	  s[0] = i+'0';
	  s[1] = j+'0';
	  s[2] = k+'0';
	  s[3] = l+'0';
	  possible.push_back(s);
	}
      }
    }
  }
  sort(possible.begin(), possible.end());
}

vector<string> erase(const vector<string>& v, const vector<Info>& in){
  vector<string> res;
  for(int i = 0; i < (int)v.size(); i++){
    bool flg = true;
    for(int j = 0; j < (int)in.size(); j++) if(v[i] == in[j].s && in[j].hit != 4) flg = false;
    if(flg) res.push_back(v[i]);
  }
  return res;
}


int main(){
  vector<string> possible;
  generate(possible);
  int N;
  while(cin >> N && N){
    vector<Info> v(N);
    memset(can, true, sizeof(can));
    for(int i = 0; i < N; i++) cin >> v[i].s >> v[i].hit >> v[i].blow;
    vector<string> ans;

    for(int i = 0; i < (int)possible.size(); i++)
      if(isValid(possible[i], v)) ans.push_back(possible[i]);
    
    ans = erase(ans, v);
    if(ans.size() == 1) cout << ans[0] << endl;
    else cout << findCritical(ans, possible) << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 1536
final_rank: 14

code_snippet: #include <iostream>
#include <algorithm>
#include <string>
#include <map>
#include <vector>
using namespace std;
int list[10000][6];
int ko[10000][4];
bool check(int a,int b,int c,int d){
	int e[10]={0};
	e[a]++;e[b]++;e[c]++;e[d]++;
	for(int i=0;i<10;i++)if(e[i]>1)return 0;
	return 1;
}

int main(){
	int N;
	while(cin>>N,N){
		int C,H,B;
		int cnt=0;
		for(int i=0;i<N;i++){
			for(int j=3;j<6;j++)cin>>list[i][j];
			for(int j=3;j>0;j--){
				list[i][j-1]=list[i][j]/10;
				list[i][j]%=10;
			}
		}
		for(int i=0;i<=9;i++){
			for(int j=0;j<=9;j++){
				for(int k=0;k<=9;k++){
					for(int l=0;l<=9;l++){
						if(check(i,j,k,l)){
							int flag=1;
							for(int m=0,h,b;m<N;m++){
								h=0;
								b=0;
								if(list[m][0]==i)h++;
								if(list[m][1]==j)h++;
								if(list[m][2]==k)h++;
								if(list[m][3]==l)h++;
								
								if(list[m][0]==j  || list[m][0]==k  || list[m][0]==l )b++;
								if(list[m][1]==i  || list[m][1]==k  || list[m][1]==l )b++;
								if(list[m][2]==i  || list[m][2]==j  || list[m][2]==l )b++;
								if(list[m][3]==i  || list[m][3]==j  || list[m][3]==k )b++;
								
								if(!(list[m][4]==h&&list[m][5]==b))flag=0;
							}
							if(flag){
								ko[cnt][0]=i;
								ko[cnt][1]=j;
								ko[cnt][2]=k;
								ko[cnt][3]=l;
								cnt++;
							}
						}
					}
				}
			}
		}
		
		if(cnt==1){
			for(int i=0;i<4;i++)cout<<ko[0][i];
			cout<<endl;
		}
		else{
			int que=-1;
			int d[6];
			for(d[4]=0123;d[4]<=9876&&que<0;d[4]++){
				d[3]=d[4];
				for(d[6]=3;d[6]>0;d[6]--){
					d[d[6]-1]=d[d[6]]/10;
					d[d[6]]%=10;
				}
				if(check(d[0],d[1],d[2],d[3])){
					int hb[5][5]={0};
					for(int i=0;i<cnt;i++){
						int h=0,b=0;
						for(int j=0;j<4;j++)if(ko[i][j]==d[j])h++;
						for(int j=0;j<4;j++)for(int k=0;k<4;k++)if(ko[i][j]==d[k])b++;
						b-=h;
						hb[h][b]++;
					}
					int flag=1;
					for(int i=0;i<5;i++)for(int j=0;j<5;j++)if(hb[i][j]>1)flag=0;
					if(flag){
						que=d[0]*1000+d[1]*100+d[2]*10+d[3];
						for(int i=0;i<4;i++)cout<<d[i];
						cout<<endl;
					}
				}
			}
			if(que<0)cout<<"????"<<endl;
		}
	}
	return 0;
}
accuracy: 1
time_ms: 920
memory_kb: 1188
final_rank: 15

code_snippet: #include <cstdio>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#include <numeric>
#include <climits>
#include <cfloat>
using namespace std;

template <size_t T>
bool nextBitset(bitset<T> &bs, int digit)
{
    if(bs.none())
        return false;
    bitset<T> x, y, z;
    x = bs.to_ulong() & (~(bs.to_ulong()) + 1ULL);
    y = bs.to_ulong() + x.to_ulong() + 0ULL;
    z = bs & ~y;
    if(bs[digit-1] && bs == z)
        return false;
    bs = ((z.to_ulong() / x.to_ulong()) >> 1) + 0ULL;
    bs |= y;
    return true;
}

pair<int, int> hitBlow(const string& s, const string& t)
{
    pair<int, int> ret(0, 0);
    for(int i=0; i<4; ++i){
        if(s[i] == t[i])
            ++ ret.first;
        else if(t.find(s[i]) != string::npos)
            ++ ret.second;
    }
    return ret;
}

int main()
{
    for(;;){
        int n;
        cin >> n;
        if(n == 0)
            return 0;

        vector<string> digit(n);
        vector<pair<int, int> > a(n);
        for(int i=0; i<n; ++i)
            cin >> digit[i] >> a[i].first >> a[i].second;

        vector<string> t;
        bitset<10> bs((1<<4)-1);
        do{
            string s;
            for(int i=0; i<10; ++i){
                if(bs[i])
                    s += '0' + i;
            }
            do{
                bool ok = true;
                for(int i=0; i<n; ++i){
                    if(hitBlow(s, digit[i]) != a[i])
                        ok = false;
                }
                if(ok)
                    t.push_back(s);
            }while(next_permutation(s.begin(), s.end()));
        }while(nextBitset(bs, 10));

        if(t.size() == 1){
            cout << t[0] << endl;
            continue;
        }

        string ret = "????";
        bs = bitset<10>((1<<4)-1);
        do{
            string s;
            for(int i=0; i<10; ++i){
                if(bs[i])
                    s += '0' + i;
            }
            do{
                set<pair<int, int> > p;
                for(unsigned i=0; i<t.size(); ++i)
                    p.insert(hitBlow(s, t[i]));
                if(p.size() == t.size())
                    ret = min(ret, s);
            }while(next_permutation(s.begin(), s.end()));
        }while(nextBitset(bs, 10));

        cout << ret << endl;
    }
}
accuracy: 1
time_ms: 2700
memory_kb: 1300
final_rank: 16

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

using namespace std;

int main(){
	ios_base::sync_with_stdio(false);
	while(true){
		int N;
		cin >> N;
		if(N == 0){ break; }
		vector<string> query(N);
		vector<int> hit(N), blow(N);
		for(int i = 0; i < N; ++i){
			cin >> query[i] >> hit[i] >> blow[i];
		}
		vector<string> solutions;
		string s = "0000";
		for(int i = 0; i < 10000; ++i){
			s[0] = i / 1000 + '0';
			s[1] = (i / 100) % 10 + '0';
			s[2] = (i / 10) % 10 + '0';
			s[3] = i % 10 + '0';
			bool valid = true;
			for(int j = 0; j < 4; ++j){
				for(int k = j + 1; k < 4; ++k){
					if(s[j] == s[k]){ valid = false; break; }
				}
			}
			if(!valid){ continue; }
			bool accept = true;
			for(int j = 0; j < N; ++j){
				int h = 0, b = 0;
				for(int k = 0; k < 4; ++k){
					for(int l = 0; l < 4; ++l){
						if(s[k] != query[j][l]){ continue; }
						if(k == l){
							++h;
						}else{
							++b;
						}
					}
				}
				if(h != hit[j] || b != blow[j]){
					accept = false;
					break;
				}
			}
			if(accept){ solutions.push_back(s); }
		}
		if(solutions.size() == 1){
			cout << solutions[0] << endl;
			continue;
		}
		string critical = "????";
		for(int i = 0; i < 10000; ++i){
			s[0] = i / 1000 + '0';
			s[1] = (i / 100) % 10 + '0';
			s[2] = (i / 10) % 10 + '0';
			s[3] = i % 10 + '0';
			bool valid = true;
			for(int j = 0; j < 4; ++j){
				for(int k = j + 1; k < 4; ++k){
					if(s[j] == s[k]){ valid = false; break; }
				}
			}
			if(!valid){ continue; }
			bool accept = true;
			int table[4][4] = { { 0 } };
			for(int j = 0; j < solutions.size(); ++j){
				int h = 0, b = 0;
				for(int k = 0; k < 4; ++k){
					for(int l = 0; l < 4; ++l){
						if(s[k] != solutions[j][l]){ continue; }
						if(k == l){
							++h;
						}else{
							++b;
						}
					}
				}
				if(table[h][b]){
					accept = false;
					break;
				}
				table[h][b] = 1;
			}
			if(accept){
				critical = s;
				break;
			}
		}
		cout << critical << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 956
final_rank: 5

code_snippet: #include<cstdio>
#include<vector>

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

using namespace std;

bool is_valid(const char *a,const char *b,int hit,int blow){
	rep(i,4) rep(j,4) if(a[i]==b[j]) {
		if(i==j) hit--;
		else     blow--;
	}
	return hit==0 && blow==0;
}

int main(){
	vector<int> cand0; // どの桁の数字も異なるような 4 桁の数
	rep(i,10000){
		char s[5]; sprintf(s,"%04d",i);
		if(!(s[0]==s[1] || s[0]==s[2] || s[0]==s[3] || s[1]==s[2] || s[1]==s[3] || s[2]==s[3]))
			cand0.push_back(i);
	}

	for(int n;scanf("%d",&n),n;){
		vector<int> in(n),hit(n),blow(n);
		rep(i,n) scanf("%d%d%d",&in[i],&hit[i],&blow[i]);

		// 入力された質問に矛盾しない数全体
		vector<int> cand;
		rep(j,cand0.size()){
			char s[5]; sprintf(s,"%04d",cand0[j]);
			bool ok=true;
			rep(i,n){
				char t[5]; sprintf(t,"%04d",in[i]);
				if(!is_valid(s,t,hit[i],blow[i])){ ok=false; break; }
			}
			if(ok) cand.push_back(cand0[j]);
		}

		if(cand.size()==1){
			printf("%04d\n",cand[0]);
			continue;
		}

		if(cand.size()>15){ // 最後の一回の発言でどうやっても特定できない ( 15 通りの返答しか得られない, 鳩ノ巣原理 )
			puts("????");
			continue;
		}

		int ans=-1;
		rep(i,cand0.size()){
			char s[5]; sprintf(s,"%04d",cand0[i]); // 最後の 1 回に発言するべき数

			bool ok=true;
			vector<int> reply(cand.size());
			rep(j,cand.size()){
				char t[5]; sprintf(t,"%04d",cand[j]);
				int hit=0,blow=0;
				rep(k,4) rep(l,4) if(s[k]==t[l]) {
					if(k==l) hit++;
					else     blow++;
				}
				reply[j]=hit*10+blow;
				rep(k,j) if(reply[k]==reply[j]) { ok=false; break; }
			}

			if(ok){ // 真の解がどれであったとしても特定できるとき
				if(ans==-1){ ans=cand0[i]; break; }
			}
		}

		if(ans!=-1) printf("%04d\n",ans);
		else        puts("????");
	}

	return 0;
}
accuracy: 1
time_ms: 220
memory_kb: 876
final_rank: 2

code_snippet: #include<cstdio>
#include<vector>

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

using namespace std;

bool is_valid(const char *a,const char *b,int hit,int blow){
	rep(i,4) rep(j,4) if(a[i]==b[j]) {
		if(i==j) hit--;
		else     blow--;
	}
	return hit==0 && blow==0;
}

int main(){
	vector<int> cand0; // どの桁の数字も異なるような 4 桁の数
	rep(i,10000){
		char s[5]; sprintf(s,"%04d",i);
		if(!(s[0]==s[1] || s[0]==s[2] || s[0]==s[3] || s[1]==s[2] || s[1]==s[3] || s[2]==s[3]))
			cand0.push_back(i);
	}

	for(int n;scanf("%d",&n),n;){
		vector<int> in(n),hit(n),blow(n);
		rep(i,n) scanf("%d%d%d",&in[i],&hit[i],&blow[i]);

		// 入力された質問に矛盾しない数全体
		vector<int> cand;
		rep(j,cand0.size()){
			char s[5]; sprintf(s,"%04d",cand0[j]);
			bool ok=true;
			rep(i,n){
				char t[5]; sprintf(t,"%04d",in[i]);
				if(!is_valid(s,t,hit[i],blow[i])){ ok=false; break; }
			}
			if(ok) cand.push_back(cand0[j]);
		}

		if(cand.size()==1){
			printf("%04d\n",cand[0]);
			continue;
		}

		if(cand.size()>16){
			puts("????");
			continue;
		}

		int ans=-1;
		rep(i,cand0.size()){
			char s[5]; sprintf(s,"%04d",cand0[i]); // 最後の 1 回に発言するべき数

			bool ok=true;
			vector<int> reply(cand.size());
			rep(j,cand.size()){
				char t[5]; sprintf(t,"%04d",cand[j]);
				int hit=0,blow=0;
				rep(k,4) rep(l,4) if(s[k]==t[l]) {
					if(k==l) hit++;
					else     blow++;
				}
				reply[j]=hit*10+blow;
				rep(k,j) if(reply[k]==reply[j]) { ok=false; break; }
			}

			if(ok){ // 真の解がどれであったとしても特定できるとき
				if(ans==-1){ ans=cand0[i]; break; }
			}
		}

		if(ans!=-1) printf("%04d\n",ans);
		else        puts("????");
	}

	return 0;
}
accuracy: 1
time_ms: 230
memory_kb: 876
final_rank: 3

code_snippet: #include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>

using namespace std;

#define FOR(i,k,n) for(int i=(k); i<(int)n; ++i)
#define REP(i,n) FOR(i,0,n)
#define FORIT(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)

template<class T> void debug(T begin, T end){ for(T i = begin; i != end; ++i) cout<<*i<<" "; cout<<endl; }

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;
typedef pair<int,int> P;
string itos(int n){
  stringstream ss;
  ss<<n;
  return ss.str();
}

int main(){
  vector<string> cand;
  FOR(n,123,10000){
    string s = itos(n);
    if(s.size() < 4) s = "0" + s;
    set<char> cnt;
    REP(i,4)cnt.insert(s[i]);
    if(cnt.size() == 4)cand.push_back(s);
  }
  int N;
  while(cin>>N, N){
    vector<string> input(N);
    vector<int> hit(N),brow(N);
    REP(i,N)cin>>input[i]>>hit[i]>>brow[i];
    vector<string> ans;
    FORIT(it, cand){
      bool ok = true;
      REP(i,N){
        int h = 0, b = 0;
        REP(j,4)REP(k,4)if((*it)[j]==input[i][k]){
          if(j == k) h++;
          else b++;
        }
        if(h != hit[i] || b != brow[i]){
          ok = false;
          break;
        }
      }
      if(ok){
        ans.push_back(*it);
      }
    }
    string ans2 = "";
    if(ans.size() > 25) goto OUTPUT;
    FORIT(it, cand){
      bool used[5][5] = {};
      bool ok = true;
      REP(i,ans.size()){
        int h = 0, b = 0;
        REP(j,4)REP(k,4)if((*it)[j]==ans[i][k]){
          if(j == k) h++;
          else b++;
        }
        if(!used[h][b])used[h][b] = true;
        else {
          ok = false;
          break;
        }
      }
      if(ok){
        ans2 = *it;
        break;
      }
    }
OUTPUT:
    if(ans.size() == 1) cout<<ans.front()<<endl;
    else if(ans2 != "") cout<<ans2<<endl;
    else cout<<"????"<<endl;
  }

  return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 1132
final_rank: 7

code_snippet: #include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>

using namespace std;

#define FOR(i,k,n) for(int i=(k); i<(int)n; ++i)
#define REP(i,n) FOR(i,0,n)
#define FORIT(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)

template<class T> void debug(T begin, T end){ for(T i = begin; i != end; ++i) cout<<*i<<" "; cout<<endl; }

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;
typedef pair<int,int> P;
string itos(int n){
  stringstream ss;
  ss<<n;
  return ss.str();
}

int main(){
  vector<string> cand;
  FOR(n,123,10000){
    string s = itos(n);
    if(s.size() < 4) s = "0" + s;
    set<char> cnt;
    REP(i,4)cnt.insert(s[i]);
    if(cnt.size() == 4)cand.push_back(s);
  }
  int N;
  while(cin>>N, N){
    vector<string> input(N);
    vector<int> hit(N),brow(N);
    REP(i,N)cin>>input[i]>>hit[i]>>brow[i];
    vector<string> ans;
    FORIT(it, cand){
      string &s = *it;
      bool ok = true;
      REP(i,N){
        int h = 0, b = 0;
        REP(j,4)REP(k,4)if(s[j]==input[i][k]){
          if(j == k) h++;
          else b++;
        }
        if(h != hit[i] || b != brow[i]){
          ok = false;
          break;
        }
      }
      if(ok){
        ans.push_back(s);
      }
    }
    vector<string> ans2;
    FORIT(it, cand){
      string &s = *it;
      set<P> pset;
      REP(i,ans.size()){
        int h = 0, b = 0;
        REP(j,4)REP(k,4)if(s[j]==ans[i][k]){
          if(j == k) h++;
          else b++;
        }
        pset.insert(P(h,b));
      }
      if(pset.size() == ans.size()){
        ans2.push_back(s);
      }
    }
    if(ans.size() == 1) cout<<ans.front()<<endl;
    else if(ans2.size() > 0) cout<<ans2.front()<<endl;
    else cout<<"????"<<endl;
  }

  return 0;
}
accuracy: 1
time_ms: 5590
memory_kb: 1236
final_rank: 20

code_snippet: #include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <set>
#include <cstring>
#include <sstream>

using namespace std;

int N;
string ss[10001];
int hit[10001];
int blow[10001];
bool isValid[10001];

bool check(string org,string tgt,int hits,int blows){
    int h=0;
    int b=0;
    for(int i=0;i<tgt.size();i++){
        if(tgt[i]==org[i]){
            h++;
        }
        else{
            bool ok=false;
            for(int j=0;j<org.size();j++){
                if(org[j]==tgt[i]){
                    ok=true;
                    break;
                }
            }
            if(ok){
                b++;
            }
        }
    }
    return (hits==h)&&(blows==b);
}
pair<int,int> getPii(string org,string tgt){
    int h=0;
    int b=0;
    for(int i=0;i<tgt.size();i++){
        if(tgt[i]==org[i]){
            h++;
        }
        else{
            bool ok=false;
            for(int j=0;j<org.size();j++){
                if(org[j]==tgt[i]){
                    ok=true;
                    break;
                }
            }
            if(ok){
                b++;
            }
        }
    }
    return make_pair(h,b);
}


int main(){

    while(cin>>N&&N){
        memset(isValid,0,sizeof(isValid));
        for(int i=0;i<N;i++)
            cin>>ss[i]>>hit[i]>>blow[i];
        // ÃÈðvZ
        int cnt=0;
        vector<string> cands;
        for(int i=123;i<10001;i++){
            int a=i;
            set<int> s;
            while(a){
                s.insert(a%10);
                a/=10;
            }
            if(i<1000)s.insert(0);
            bool ok=true;
            stringstream sss;
            sss<<i;
            string org=sss.str();
            if(s.size()==4){
                if(org.size()==3)org='0'+org;
                // eÉÂ¢ÄhitÆblowª³µ¢©vZ
                for(int j=0;j<N;j++){
                    ok&=check(org,ss[j],hit[j],blow[j]);
                    if(!ok)break;
                }
            }
            else ok=false;
            isValid[i]=ok;
            if(isValid[i]){
                cnt++;
                cands.push_back(org);
            }
        }
        if(cnt==0)cout<<"????"<<endl;
        else if(cnt==1){
            for(int i=123;i<=10000;i++){
                if(isValid[i]){
                    stringstream sss;
                    sss<<i;
                    string os=sss.str();
                    if(os.size()==3)os='0'+os;
                    cout<<os<<endl;
                    break;
                }
            }
        }
        // ¡óâª éê,ÔÉ²×é
        else{
            bool ok=false;
            for(int i=123;i<10001;i++){
                stringstream sss;
                sss<<i;
                string org=sss.str();
                if(org.size()==3)org='0'+org;
                set<char> sc;
                for(int i=0;i<org.size();i++)sc.insert(org[i]);
                if(sc.size()!=4)continue;

                set<pair<int,int> >  spii;
                // hitÆblowÌð¦é
                int prv=0;
                for(int j=0;j<cands.size();j++){
                    spii.insert(getPii(cands[j],org));
                    if(spii.size()!=prv+1)break;
                    else prv=spii.size();
                }
                if(spii.size()==cands.size()){
                    cout<<org<<endl;
                    ok=true;
                    break;
                }
            }
            if(!ok)cout<<"????"<<endl;
        }
    }

    return 0;
}
accuracy: 1
time_ms: 2280
memory_kb: 0
final_rank: 12

code_snippet: #include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <set>
#include <cstring>
#include <sstream>

using namespace std;

int N;
string ss[10001];
int hit[10001];
int blow[10001];
bool isValid[10001];

bool check(string org,string tgt,int hits,int blows){
    int h=0;
    int b=0;
    for(int i=0;i<tgt.size();i++){
        if(tgt[i]==org[i]){
            h++;
        }
        else{
            bool ok=false;
            for(int j=0;j<org.size();j++){
                if(org[j]==tgt[i]){
                    ok=true;
                    break;
                }
            }
            if(ok){
                b++;
            }
        }
    }
    return (hits==h)&&(blows==b);
}
pair<int,int> getPii(string org,string tgt){
    int h=0;
    int b=0;
    for(int i=0;i<tgt.size();i++){
        if(tgt[i]==org[i]){
            h++;
        }
        else{
            bool ok=false;
            for(int j=0;j<org.size();j++){
                if(org[j]==tgt[i]){
                    ok=true;
                    break;
                }
            }
            if(ok){
                b++;
            }
        }
    }
    return make_pair(h,b);
}


int main(){

    while(cin>>N&&N){
        memset(isValid,0,sizeof(isValid));
        for(int i=0;i<N;i++)
            cin>>ss[i]>>hit[i]>>blow[i];
        // ÃÈðvZ
        int cnt=0;
        vector<string> cands;
        for(int i=123;i<10001;i++){
            int a=i;
            set<int> s;
            while(a){
                s.insert(a%10);
                a/=10;
            }
            if(i<1000){
                s.insert(0);
            }
            bool ok=true;
            stringstream sss;
            sss<<i;
            string org=sss.str();
            if(s.size()==4){
                if(org.size()==3)org='0'+org;
                // eÉÂ¢ÄhitÆblowª³µ¢©vZ
                for(int j=0;j<N;j++){
                    ok&=check(org,ss[j],hit[j],blow[j]);
                    if(!ok)break;
                }
            }
            else ok=false;
            isValid[i]=ok;
            if(isValid[i]){
                cnt++;
                cands.push_back(org);
            }
        }
        if(cnt==0)cout<<"????"<<endl;
        else if(cnt==1){
            for(int i=123;i<=10000;i++){
                if(isValid[i]){
                    stringstream sss;
                    sss<<i;
                    string os=sss.str();
                    if(os.size()==3)os='0'+os;
                    cout<<os<<endl;
                    break;
                }
            }
        }
        // ¡óâª éê,ÔÉ²×é
        else{
            bool ok=false;
            for(int i=123;i<10001;i++){
                stringstream sss;
                sss<<i;
                string org=sss.str();
                if(org.size()==3)org='0'+org;
                set<char> sc;
                for(int i=0;i<org.size();i++)sc.insert(org[i]);
                if(sc.size()!=4)continue;

                set<pair<int,int> >  spii;
                // hitÆblowÌð¦é
                int prv=0;
                for(int j=0;j<cands.size();j++){
                    spii.insert(getPii(org,cands[j]));
                    if(spii.size()!=prv+1)break;
                    else prv=spii.size();
                }
                if(spii.size()==cands.size()){
                    cout<<org<<endl;
                    ok=true;
                    break;
                }
            }
            if(!ok)cout<<"????"<<endl;
        }
    }

    return 0;
}
accuracy: 1
time_ms: 2280
memory_kb: 0
final_rank: 12

code_snippet: #include <iostream>
#include <iomanip>
#include <sstream>
#include <cstdio>
#include <string>
#include <vector>
#include <algorithm>
#include <complex>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <cassert>
#include <climits>
#include <queue>
#include <set>
#include <map>
#include <valarray>
#include <bitset>
#include <stack>
using namespace std;

#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()
typedef long long ll;
typedef pair<int,int> pii;
const int INF = 1<<29;
const double PI = acos(-1);
const double EPS = 1e-8;
int n;
string S[100];
int H[100], B[100];
string str;
set<string> se;
void func(int pos, int used) {
  if (pos == 4) {
    bool f = 1;
    REP(i, n) {
      int h=0,b=0;
      REP(j,4) {
        if (S[i][j]==str[j]) h++;
        if (used>>(S[i][j]-'0')&1) b++;
      }
      b -= h;
      if (H[i] != h || B[i] != b) {
        f = 0;
        break;
      }
    }
    if (f) se.insert(str);
    return;
  }
  REP(i, 10) {
    if (used>>i&1) continue;
    str[pos] = '0'+i;
    func(pos+1, used|1<<i);
  }
}
bool table[4][4];
bool func2(int pos, int used) {
  if (pos == 4) {
    memset(table, 0, sizeof(table));
    FOR(it, se) {
      int h=0,b=0;
      string t = *it;
      REP(j,4) {
        if (t[j]==str[j]) h++;
        if (used>>(t[j]-'0')&1) b++;
      }
      b -= h;
      if (table[h][b]) return 0;
      table[h][b] = 1;
    }
    return 1;
  }
  REP(i, 10) {
    if (used>>i&1) continue;
    str[pos] = '0'+i;
    if (func2(pos+1, used|1<<i)) return 1;
  }
  return 0;
}



int main() {
  while(cin >> n, n) {
    REP(i, n) {
      cin >> S[i] >> H[i] >> B[i];
    }
    se.clear();
    str = "0000";
    func(0,0);
    
    if(se.size() == 1) {
      cout << *se.begin() << endl;
    } else if(se.size() >= 2 && func2(0, 0)) {
      cout << str << endl;
    } else {
      cout << "????" << endl;
    }
    
  }
}
accuracy: 1
time_ms: 80
memory_kb: 0
final_rank: 1

code_snippet: #include<iostream>
#include<vector>
#include<utility>
using namespace std;

string itos(int a){
  string s;
  int k = 1000;
  for(int i=0;i<4;i++){
    s.push_back(a/k+'0');
    a -= (a/k)*k;
    k/=10;
  }
  return s;
}

pair<int,int> hitblow(string a,string b){
  pair<int,int> res;
  res.first = 0;
  res.second = 0;
  bool ca[10],cb[10];
  for(int i=0;i<10;i++){
    ca[i] = false;
    cb[i] = false;
  }
  for(int i=0;i<(int)a.size();i++){
    if(a[i] == b[i])res.first++;
    else{
      ca[a[i]-'0'] = true;
      cb[b[i]-'0'] = true;
      if(cb[a[i]-'0'])res.second++;
      if(ca[b[i]-'0'])res.second++;
    }
  }
  return res;
}

int main(){
  bool check[10000],hoge[10000];
  string str;
  int h,b,n;

  for(int i=0;i<10;i++){
    for(int j=0;j<10;j++){
      for(int k=0;k<10;k++){
	for(int l=0;l<10;l++){
	  if(i==j || i== k|| i==l || j==k || j==l || k==l){
	    hoge[i*1000+j*100+k*10+l] = false;
	  }else{
	    hoge[i*1000+j*100+k*10+l] = true;
	  }
	}
      }
    }
  }

  while(1){
    cin >> n;
    if(!n)break;

    for(int i=0;i<10000;i++)check[i] = hoge[i];

    for(int i=0;i<n;i++){
      cin >> str >> h >> b;
      for(int i=0;i<10000;i++){
	if(check[i]){
	  pair<int,int> tmp;
	  tmp = hitblow(itos(i),str);
	  check[i] = (tmp.first == h) && (tmp.second == b);
	}
      }
    }
 
    int c = 0;
    for(int i=0;i<10000;i++){
      if(check[i])c++;
    }
    if(c==1){
      for(int i=0;i<10000;i++){
	if(check[i])cout << itos(i) << endl;
      }
    }else{
      vector<int> can;
      for(int i=0;i<10000;i++){
	if(check[i])can.push_back(i);
      }
      int i;
      for(i=0;i<10000;i++){
	if(hoge[i]){
	  int hb[5][5];
	  for(int j=0;j<5;j++){
	    for(int k=0;k<5;k++)hb[j][k] = 0;
	  }
	  bool f = true;
	  for(int j=0;j<(int)can.size();j++){
	    pair<int,int> tmp;
	    tmp = hitblow(itos(i),itos(can[j]));
	    hb[tmp.first][tmp.second]++;
	    if(hb[tmp.first][tmp.second]>=2){
	      f = false;
	      break;
	    }
	  }

	  if(f){
	    cout << itos(i) << endl;
	    break;
	  }
	}
      }
      if(i==10000)cout << "????" << endl;
    }
  }
}
accuracy: 1
time_ms: 540
memory_kb: 948
final_rank: 10

code_snippet: #include<iostream>
#include<vector>
#include<utility>
using namespace std;

string itos(int a){
  string s;
  int k = 1000;
  for(int i=0;i<4;i++){
    s.push_back(a/k+'0');
    a -= (a/k)*k;
    k/=10;
  }
  return s;
}

pair<int,int> hitblow(string a,string b){
  pair<int,int> res;
  int c = 0;
  bool ca[10],cb[10];
  for(int i=0;i<10;i++){
    ca[i] = false;
    cb[i] = false;
  }
  for(int i=0;i<(int)a.size();i++){
    if(a[i] == b[i])c++;
    ca[a[i]-'0'] = true;
    cb[b[i]-'0'] = true;
  }

  res.first = c;
  c = 0;
  for(int i=0;i<10;i++){
    if(ca[i] && cb[i])c++;
  }
  res.second = c - res.first;

  return res;
}

int main(){
  bool check[10000],hoge[10000];
  string str;
  int h,b,n;

  for(int i=0;i<10;i++){
    for(int j=0;j<10;j++){
      for(int k=0;k<10;k++){
	for(int l=0;l<10;l++){
	  if(i==j || i== k|| i==l || j==k || j==l || k==l){
	    hoge[i*1000+j*100+k*10+l] = false;
	  }else{
	    hoge[i*1000+j*100+k*10+l] = true;
	  }
	}
      }
    }
  }

  while(1){
    cin >> n;
    if(!n)break;

    for(int i=0;i<10000;i++)check[i] = hoge[i];

    for(int i=0;i<n;i++){
      cin >> str >> h >> b;
      for(int i=0;i<10000;i++){
	if(check[i]){
	  pair<int,int> tmp;
	  tmp = hitblow(itos(i),str);
	  check[i] = (tmp.first == h) && (tmp.second == b);
	}
      }
    }
 
    int c = 0;
    for(int i=0;i<10000;i++){
      if(check[i])c++;
    }
    if(c==1){
      for(int i=0;i<10000;i++){
	if(check[i])cout << itos(i) << endl;
      }
    }else{
      vector<int> can;
      for(int i=0;i<10000;i++){
	if(check[i])can.push_back(i);
      }
      int i;
      for(i=0;i<10000;i++){
	if(hoge[i]){
	  int hb[5][5];
	  for(int j=0;j<5;j++){
	    for(int k=0;k<5;k++)hb[j][k] = 0;
	  }
	  bool f = true;
	  for(int j=0;j<(int)can.size();j++){
	    pair<int,int> tmp;
	    tmp = hitblow(itos(i),itos(can[j]));
	    hb[tmp.first][tmp.second]++;
	    if(hb[tmp.first][tmp.second]>=2){
	      f = false;
	      break;
	    }
	  }

	  if(f){
	    cout << itos(i) << endl;
	    break;
	  }
	}
      }
      if(i==10000)cout << "????" << endl;
    }
  }
}
accuracy: 1
time_ms: 560
memory_kb: 952
final_rank: 11

code_snippet: #include<iostream>
#include<algorithm>
#include<vector>
#include<cstdio>
#include<cassert>
using namespace std;
#define REP(i,b,n) for(int i=b;i<n;i++)
#define rep(i,n)   REP(i,0,n)
typedef pair<int,int> pii;
const int N = 10000;

void compute(int i,int *buf){
  buf[0]=i/1000%10;
  buf[1]=i/100%10;
  buf[2]=i/10%10;
  buf[3]=i%10;
}

pii hitAndBlow(int n,int q){
  int hit=0,blow=0;
  int buf1[5],buf2[5];
  compute(n,buf1);
  compute(q,buf2);
  rep(i,4){
    rep(j,4){
      if (buf1[i] == buf2[j]){
	if (i == j)hit++;
	else blow++;
      }
    }
  }
  return make_pair(hit,blow);
}

int solve(vector<int> &a,vector<int> all){
  if (a.size() > 15)return -1;
  rep(i,all.size()){
    int buf[5];
    bool isok=true;
    int cnt[5][5]={0};
    rep(j,a.size()){
      pii tmp = hitAndBlow(a[j],all[i]);
      cnt[tmp.first][tmp.second]++;
      if (cnt[tmp.first][tmp.second] > 1)isok=false;
    }
    if (isok)return all[i];
  }
  return -1;
}

main(){
  int n;
  vector<int> all(N);
  rep(i,N){
    int buf[4];
    compute(i,buf);
    bool isok=true;
    rep(j,4)REP(k,j+1,4)if (buf[j] == buf[k]){isok=false;}
    all[i]=(isok?i:-1);
  }
  sort(all.begin(),all.end());
  all.erase(remove(all.begin(),all.end(),-1),all.end());
  while(cin>>n && n){
    /*
    vector<pii> in(n);
    vector<int> cand,query(n);
    rep(i,n)cin>>query[i]>>in[i].first>>in[i].second;
    rep(i,all.size()){
      bool isok=true;
      int buf[5];
      rep(j,n){
	pii tmp =hitAndBlow(all[i],query[j]);
	if (tmp.first == in[j].first && tmp.second == in[j].second);
	else {
	  isok=false;
	}
      }
      if (isok)cand.push_back(all[i]);
    }
    sort(cand.begin(),cand.end());
    */
    vector<int> cand;
    cand=all;
    rep(k,n){
      vector<int> b;
      int q,hit,blow;
      cin>>q>>hit>>blow;
      rep(i,cand.size()){
	bool isok=true;
	pii tmp =hitAndBlow(q,cand[i]);
	if (hit == tmp.first && blow == tmp.second);
	else {
	  isok=false;
	}
	if (isok)b.push_back(cand[i]);
      }
      cand=b;
    }
    int ans = cand.size() == 1?cand[0]:solve(cand,all);
    if (ans !=-1)printf("%04d\n",ans);
    else puts("????");
  }
  return false;
}
accuracy: 1
time_ms: 60
memory_kb: 1000
final_rank: 4