SHOW:
|
|
- or go back to the newest paste.
| 1 | #include <sstream> | |
| 2 | #include <iostream> | |
| 3 | #include <iomanip> | |
| 4 | #include <ext/stdio_filebuf.h> | |
| 5 | #include <string> | |
| 6 | #include <set> | |
| 7 | #include <vector> | |
| 8 | #include <algorithm> | |
| 9 | #include <cstdlib> | |
| 10 | #include <climits> | |
| 11 | #include <ctime> | |
| 12 | using namespace std; | |
| 13 | ||
| 14 | #define lrotl(val,rot) (( (val)<<(rot) )|( (val)>>(sizeof(val)*CHAR_BIT-(rot)) )) | |
| 15 | static unsigned int x = 123456789; | |
| 16 | static unsigned int y = 362436069; | |
| 17 | static unsigned int z = 521288629; | |
| 18 | static unsigned int w = 88675123; | |
| 19 | ||
| 20 | unsigned int xor_rand(){
| |
| 21 | unsigned int t; | |
| 22 | t=x^(x<<11); | |
| 23 | x=y;y=z;z=w; | |
| 24 | return w=(w^(w>>19)) ^ (t^(t>>8)); | |
| 25 | } | |
| 26 | ||
| 27 | // http://d.hatena.ne.jp/gintenlabo/20100930/1285859540 | |
| 28 | void xor_srand(unsigned int seed){
| |
| 29 | #if 1 | |
| 30 | x^=seed; | |
| 31 | y^=lrotl(seed,17); | |
| 32 | z^=lrotl(seed,31); | |
| 33 | w^=lrotl(seed,18); | |
| 34 | #else | |
| 35 | x^=lrotl(seed,14); | |
| 36 | y^=lrotl(seed,31); | |
| 37 | z^=lrotl(seed,13); | |
| 38 | w^=seed; | |
| 39 | #endif | |
| 40 | } | |
| 41 | ||
| 42 | static unsigned int _random(unsigned int max){return xor_rand()%max;}
| |
| 43 | ||
| 44 | int _main(ostream &pout,istream &pin){ //actual validator
| |
| 45 | xor_srand((unsigned int)time(NULL)^(getpid()<<16)); | |
| 46 | string TAG="[Validator] "; | |
| 47 | ostringstream oanswer; | |
| 48 | oanswer<<setw(9)<<setfill('0')<<xor_rand()%1000000000;
| |
| 49 | string answer=oanswer.str(),op,tmp; | |
| 50 | cerr<<TAG<<"Answer: "<<answer<<endl<<flush; | |
| 51 | ||
| 52 | set<string>s; | |
| 53 | int test=0; | |
| 54 | ||
| 55 | //cerr<<TAG<<"Listening."<<endl<<flush; | |
| 56 | for(;;test++){
| |
| 57 | pin>>op; | |
| 58 | if(op=="?"){
| |
| 59 | cerr<<TAG<<"<Test>"<<flush; | |
| 60 | if(test==21){
| |
| 61 | cerr<<TAG<<"Verdict:"<<endl<<flush; | |
| 62 | cout<<"QueryLimitExceeded"<<endl; | |
| 63 | return 0; | |
| 64 | } | |
| 65 | vector<string> arg; | |
| 66 | vector<pair<int,int> >hit_blow; | |
| 67 | int i,j,k; | |
| 68 | for(i=0;i<9;i++){
| |
| 69 | pin>>tmp; | |
| 70 | cerr<<" "<<tmp<<flush; | |
| 71 | if(tmp.length()!=9||find(s.begin(),s.end(),tmp)!=s.end()){
| |
| 72 | cerr<<endl<<TAG<<"Verdict is:"<<endl<<flush; | |
| 73 | cout<<"RuntimeError"<<endl; | |
| 74 | return 0; | |
| 75 | } | |
| 76 | arg.push_back(tmp); | |
| 77 | s.insert(tmp); | |
| 78 | } | |
| 79 | cerr<<endl<<flush; | |
| 80 | for(i=0;i<9;i++){
| |
| 81 | int hit=0,blow=0; | |
| 82 | for(j=0;j<9;j++) | |
| 83 | if(answer[j]==arg[i][j])hit++; | |
| 84 | for(j='0';j<='9';j++){ //modifiable
| |
| 85 | int c1=0,c2=0; | |
| 86 | for(k=0;k<9;k++){
| |
| 87 | if(answer[k]==j)c1++; | |
| 88 | if(arg[i][k]==j)c2++; | |
| 89 | } | |
| 90 | blow+=min(c1,c2); | |
| 91 | } | |
| 92 | hit_blow.push_back(make_pair(hit,blow-hit)); | |
| 93 | } | |
| 94 | random_shuffle(hit_blow.begin(),hit_blow.end(),_random); | |
| 95 | ostringstream x; | |
| 96 | for(i=0;i<9;i++){
| |
| 97 | if(i)x<<' '; | |
| 98 | x<<hit_blow[i].first; | |
| 99 | x<<' '; | |
| 100 | x<<hit_blow[i].second; | |
| 101 | } | |
| 102 | cerr<<TAG<<"Result: "<<x.str()<<endl<<flush; | |
| 103 | pout<<x.str()<<endl<<flush; | |
| 104 | }else if(op=="!"){
| |
| 105 | cerr<<TAG<<"<Challenge> "<<flush; | |
| 106 | pin>>tmp; | |
| 107 | cerr<<tmp<<endl<<flush; | |
| 108 | cerr<<TAG<<"Verdict:"<<endl<<flush; | |
| 109 | if(answer!=tmp){
| |
| 110 | cout<<"WrongAnswer"<<endl; | |
| 111 | }else if(10<=test){
| |
| 112 | cout<<"Accepted100"<<endl; | |
| 113 | }else{
| |
| 114 | cout<<"Accepted150"<<endl; | |
| 115 | } | |
| 116 | return 0; | |
| 117 | }else{
| |
| 118 | cerr<<TAG<<"Verdict:"<<endl<<flush; | |
| 119 | cout<<"RuntimeError"<<endl; | |
| 120 | return 0; | |
| 121 | } | |
| 122 | } | |
| 123 | return 0; | |
| 124 | } | |
| 125 | ||
| 126 | //Reactive | |
| 127 | int main(int argc, char **argv){
| |
| 128 | if(argc<2){
| |
| 129 | cerr<<"validator [program]"<<endl; | |
| 130 | cerr<<"program must be chmod +x"<<endl; | |
| 131 | return 0; | |
| 132 | } | |
| 133 | const char *cmd=argv[1]; | |
| 134 | ||
| 135 | //Initialize | |
| 136 | int fd_in[2],fd_out[2]; | |
| 137 | pipe(fd_in); | |
| 138 | pipe(fd_out); | |
| 139 | ||
| 140 | int pid=fork(); | |
| 141 | if(pid==-1){
| |
| 142 | cout<<"InternalError"<<endl; | |
| 143 | return 0; | |
| 144 | } | |
| 145 | if(pid==0){//child
| |
| 146 | close(0); | |
| 147 | dup2(fd_in[0],0); | |
| 148 | close(1); | |
| 149 | dup2(fd_out[1],1); | |
| 150 | close(fd_in[0]); | |
| 151 | close(fd_in[1]); | |
| 152 | close(fd_out[0]); | |
| 153 | close(fd_out[1]); | |
| 154 | execl(cmd,cmd,NULL); | |
| 155 | return 0; | |
| 156 | } | |
| 157 | //parent | |
| 158 | close(fd_in[0]); | |
| 159 | close(fd_out[1]); | |
| 160 | FILE *fout=fdopen(fd_in[1],"w"); | |
| 161 | FILE *fin=fdopen(fd_out[0],"r"); | |
| 162 | __gnu_cxx::stdio_filebuf<char> bout(fout, ios_base::out); | |
| 163 | __gnu_cxx::stdio_filebuf<char> bin(fin, ios_base::in); | |
| 164 | ostream pout(&bout); | |
| 165 | istream pin(&bin); | |
| 166 | _main(pout,pin); | |
| 167 | fclose(fout); | |
| 168 | fclose(fin); | |
| 169 | return 0; | |
| 170 | } |