##C++, The Scientist
This one tries to, with the history of what the majority chose per round in wave
(majority()
gives the majority's choice on a round), fit a wave to the data, of wavelength 2*period
and phase phase
. Thus, given 0,1,1,1,0,1,0,1,1,1,0,0,0,1,0
it selects period=3, phase=5
(maxat=={3,5}
): its scores become 9 3 11 5 5 3 5 7 9 7 7 7 7 7 7
. It loops over all possible periods and if, for that period, the score is higher than for the current maximum, it stores {period,phase}
for which that occurred.
It then extrapolates the found wave to the next round and takes the predicted majority.
#include <iostream>
#include <utility>
#include <cstdlib>
#include <cstring>
using namespace std;
int majority(const char *r){
int p=0,a=0,b=0;
while(true){
if(r[p]=='1')a++;
else if(r[p]=='0')b++;
else break;
p++;
}
return a>b;
}
int main(int argc,char **argv){
if(argc==1){
cout<<(rand()%2?"good":"evil")<<endl;
return 0;
}
int nump,numr;
nump=strchr(argv[1],',')-argv[1];
numr=(strlen(argv[1])+1)/(nump+1);
int period,r;
int *wave=new int[numr];
bool allequal=true;
cerr<<"wave: ";
for(r=0;r<numr;r++){
wave[r]=majority(argv[1]+r*(nump+1));
if(wave[r]!=wave[0])allequal=false;
cerr<<wave[r]<<" ";
}
cerr<<endl;
if(allequal){
cerr<<"All equal!"<<endl;
if(numr>=50){ //if it's stable, minority
if(wave[0]==1)cout<<"evil"<<endl;
else cout<<"good"<<endl;
} else { //else, majority for safety
if(wave[0]==1)cout<<"good"<<endl;
else cout<<"evil"<<endl;
}
return 0;
}
int score,*scores=new int[numr];
int max=0; //some score will always get above 0, because if some score<0, the inverted wave will be >0.
int phase,phasemax;
pair<int,int> maxat(-1,-1); //period, phase
cerr<<"scores: ";
for(period=1;period<=numr;period++){
scores[period-1]=0;
phasemax=-1;
for(phase=0;phase<2*period;phase++){
score=0;
for(r=0;r<numr;r++){
if(wave[r]==1-(r+phase)%(2*period)/period)score++;
else score--;
}
if(score>scores[period-1]){
scores[period-1]=score;
phasemax=phase;
}
}
if(scores[period-1]>max){
max=scores[period-1];
maxat.first=period;
maxat.second=phasemax;
}
cerr<<scores[period-1]<<" ";
}
cerr<<"(max="<<max<<" at {"<<maxat.first<<","<<maxat.second<<"})"<<endl;
cerr<<" max: ("<<numr<<"+"<<maxat.second<<")%(2*"<<maxat.first<<")/"<<maxat.first<<"=="<<((numr+maxat.second)%(2*maxat.first)/maxat.first)<<endl;
if((numr+maxat.second)%(2*maxat.first)/maxat.first==0)cout<<"good"<<endl;
else cout<<"evil"<<endl;
delete[] wave;
delete[] scores;
return 0;
}
Compile with g++ -O3 -o Scientist Scientist.cpp
(you don't need warnings, so no -Wall
) and run with Scientist.exe
(possibly including the argument of course). If you ask really nicely I can provide you with a Windows executable.
Oh, and don't dare messing with the input format. It'll do strange things otherwise.