#include <iostream>
#include <iomanip>
#include <ciso646>
using namespace std;
#define SNES 1
//#define READ_SEQUENCE 226826
// best genesis "BBBBBBB.B...B...B..BBBBB" ----- 454272
// best snes "Y.Y.YYYYY..Y...Y..YYYYYY" ----- 226826
const int START_FRAME=SNES?2000:2000;
const int START_X=SNES?176:40;
const int END_FRAME=SNES?2100:2080;
const char RUN_KEY=SNES?'Y':'B';
const int RB_FRAMES=8;
const int TOTAL_FRAMES=32-RB_FRAMES;
int frame;
int x;
int speed;
bool running;
bool stop;
void Display(bool R=false,bool B=false)
{
cout<<frame<<" "<<(R?'R':'.')<<(B?RUN_KEY:'.')<<" x="<<setw(14)<<left<<x/65536.0<<"speed="<<speed<<endl;
}
#if !SNES
void Run(bool R,bool B)
{
#if READ_SEQUENCE
Display(R,B);
#endif
if(R)
{
if(speed==0)
{
speed=B?150:50;
}
if(B)
{
if(stop)
{
speed=speed<150?430:speed+100;
stop=false;
running=true;
}
else if(not running)
{
running=true;
speed+=210;
}
else
{
speed=speed>768?speed-70:speed+70;
}
}
else
{
if(stop)
{
speed=speed<50?75:speed-25;
stop=false;
}
else if(not running)
{
speed=speed>384?speed-25:speed+25;
}
else
{
if(speed<334)
{
speed+=75;
running=false;
}
else if(speed<359)
{
speed+=50;
running=false;
}
else if(speed<384)
{
speed+=25;
}
else if(speed<409)
{
running=false;
}
else
{
speed-=25;
}
}
}
}
else if(speed>0)
{
if(B or speed>433)
{
speed=-1;//glisse...
}
else if(stop)
{
speed-=25;
if(speed<25)
{
speed=0;
stop=false;
}
}
else
{
if(not running)
{
speed=speed>384?speed-25:speed+25;
}
else if(speed<384)
{
speed-=25;
}
else
{
speed-=75;
}
stop=true;
}
running=false;
}
x+=speed*256;
++frame;
}
#endif
#if SNES
void Run(bool R,bool B)
{
#if READ_SEQUENCE
Display(R,B);
#endif
if(R)
{
if(speed==0)
{
if(stop)
speed=50;
stop=false;
}
if(B)
{
if(stop)
{
speed=speed<150?290:speed+50;
stop=false;
running=true;
}
else if(not running)
{
speed+=140;
running=true;
}
else
{
speed=speed>768?speed-70:speed+70;
running=true;
}
}
else
{
if(stop)
{
speed=speed<50?75:speed-20;
stop=false;
}
else if(not running)
{
speed=speed>384?speed-25:speed+25;
}
else
{
if(speed<359)
{
speed+=50;
running=false;
}
else
{
speed-=25;
}
}
}
}
else if(speed>0)
{
if(B or running)
{
speed=-1;//glisse...
}
else if(stop)
{
speed=speed<45?0:speed-20;
}
else
{
speed=speed>384?speed-25:speed+25;
stop=true;
}
running=false;
}
x+=speed*256;
++frame;
}
#endif
void Read(const char* str)
{
int i=0;
char c;
while(c=str[i++])
{
Run(true,c=='B' or c=='Y');
}
}
void Read(unsigned int key)
{
for(int i=0; i<TOTAL_FRAMES; ++i)
{
bool r=i==0?true:!((key>>(TOTAL_FRAMES-1))&1);
Run(r,!(key&1));
key>>=1;
}
}
void Init()
{
frame=START_FRAME;
x=START_X*65536;
speed=0;
running=false;
stop=false;
}
int main()
{
cout.precision(11);
#if READ_SEQUENCE
Init();
Read(READ_SEQUENCE);
for(int i=END_FRAME-START_FRAME-TOTAL_FRAMES; i>0; --i)
Run(true,true);
Display();
exit(0);
#endif
int xmax=0;
const unsigned int max=0xffffffffu;
unsigned int pct=max/100;
int pctn=0;
unsigned int key=0x00000000u;
while(key<max)
{
Init();
Read(key);
for(int i=END_FRAME-START_FRAME-TOTAL_FRAMES; i>0; --i)
Run(true,true);
if(x>xmax)
{
xmax=x;
cout<<"xmax ! "<<xmax/65536.0<<" key="<<key<<endl;
}
if(key==pct)
{
cout<<++pctn<<"%"<<endl;
pct+=max/100;
}
++key;
}
cout<<key<<endl;
return 0;
}