
#include <iostream>
#include <iomanip>
#include <string>
#include <cstdlib>
#include <ctime>
using namespace std ;
const int DIGIT_NO = 4 ;
const int MAX_NO = 10000 ;
// 字串轉整數
int atoi( const string& a ) {
int no = 0 ;
for ( int i = 0 ; i < a.size() ; ++i ) no = no * 10 + ( a[i] - '0' ) ;
return no ;
}
// 整數轉字串
string itoa( int a ) {
string no(DIGIT_NO,'0') ;
int r ;
for ( int i = 1 ; i <= DIGIT_NO ; i++ ) {
r = a % 10 ;
no[DIGIT_NO-i] = r + '0' ;
a = a / 10 ;
}
return no ;
}
// 檢查字串數字是否為有效數
bool valid_number( string no ) {
int i , j ;
for ( i = 0 ; i < DIGIT_NO ; ++i ) {
for ( j = i+1 ; j < DIGIT_NO ; ++j ) {
if ( no[i] == no[j] ) return false ;
}
}
return true ;
}
// 檢查整數是否為有效數
bool valid_number( int no ) { return valid_number(itoa(no)) ; }
// 產生一有效整數
int create_number() {
int no ;
while( 1 ) {
no = rand() % MAX_NO ;
if ( valid_number(no) ) return no ;
}
}
// 產生一靠近 n 的有效字串整數
string generate_next_number( string n ) {
int no ;
if ( n.size() ) {
no = atoi(n) ;
do {
++no ;
if ( no > 9876 ) no = 123 ;
} while ( ! valid_number(no) ) ;
} else {
no = create_number() ;
}
return itoa(no) ;
}
// 記錄結果 r (xAyB) 於 a[i] 與 b[i]
void record_answer( string r , int a[] , int b[] , int i ) {
int k ;
for ( k = 1 ; k < 4 ; ++k ) {
if ( r[k] == 'a' || r[k] == 'A' ) break ;
}
a[i] = ( k == 4 ? 0 : r[--k] - '0' ) ;
for ( k = 1 ; k < 4 ; ++k ) {
if ( r[k] == 'b' || r[k] == 'B' ) break ;
}
b[i] = ( k == 4 ? 0 : r[--k] - '0' ) ;
}
// 比較兩字串數字 no1 與 no2 為幾個 na 幾個 nb
void string_number_comparison( string no1 , string no2 , int& na , int& nb ) {
int i , j ;
na = 0 ;
for ( i = 0 ; i < DIGIT_NO ; ++i ) {
if ( no1[i] == no2[i] ) ++na ;
}
nb = 0 ;
for ( i = 0 ; i < DIGIT_NO ; ++i ) {
for ( j = 0 ; j < DIGIT_NO ; ++j ) {
if ( i == j ) continue ;
if ( no1[i] == no2[j] ) {
++nb ;
break ;
}
}
}
}
// 檢查字串數字 no 是否為滿足所有猜過條件的數字
bool good_guess( string no , string guess_number[] , int a[] , int b[] , int n ) {
int i , na , nb ;
for ( i = 0 ; i <= n ; ++i ) {
string_number_comparison(no,guess_number[i],na,nb) ;
if ( na != a[i] || nb != b[i] ) return false ;
}
return true ;
}
int main() {
const int MAX = 20 ;
string no , result ;
string guess_number[MAX] ;
int i , j , a[MAX] , b[MAX] ;
srand( static_cast<unsigned int>(time(NULL)) ) ;
string initial_number = generate_next_number(no) ;
no = initial_number ;
i = 0 ;
do {
guess_number[i] = no ;
cout << i+1 << "> " << no << "\n" << ">> " ;
cin >> result ;
record_answer(result,a,b,i) ;
if ( a[i] == 4 ) break ;
do {
no = generate_next_number(no) ;
if ( no == initial_number ) {
cout << "\n> no such number exists !" << endl ;
return 1 ;
}
} while ( ! good_guess(no,guess_number,a,b,i) ) ;
cout << endl ;
++i ;
} while ( 1 ) ;
return 0 ;
}