//	This source and Text sequences' binary patterns method apply to GNU General Public License. 
//			Copyright (C) 2015  Jasenko Dzinleski 

//	This source applies to the GNU General Public License as
//	published by the Free Software Foundation 
//	and can not be used, copied, sold, redistributed or 
//	used in any other way but only by written permission by Jasenko Dzinleski . 
//	Copyright (C) from 2001 - 2013 and later by Jasenko Dzinleski 

//	This program is distributed in the hope that it will be useful, but
//	WITHOUT ANY WARRANTY; without even the implied warranty of
//	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
//	General Public License for more details. 

//	You should have received a copy of the GNU General Public License along
//	with this program; if not, write to the Free Software Foundation, Inc.,
//	51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

//
//		Text sequences' binary patterns
//		written by Dzinleski Jasenko March , 2015 , 2016
//


#include <stdio.h>
#include <stdlib.h>

char	fn1[256]="fasta__.txt";
char	ofn1[256]="out_.txt";
char	ofn2[256]="12-2-23.txt";
char	ofn3[256]="1-12-23.txt";

FILE	*f1,*f2,*f3,*f4,*f5,*f6;

int bl[10000][4*4+1+5];
int bli=0;
int bl_[4*4];
int bl_i;

int pm_x,pj_x,pm_n,pj_n;

int df=0;

int 	bla[10000][10000][3+1];
int	ba[256][256][256][3];
int	ba_1=0;
int	ba_2=0;
int	ba_3=0;
int	ca[10000][3][3];

int p_mx(int bn , int n , int fl)
{

int i,j,k,l,m;
int a,b,c;
int bf,pm,pj,lbn=0,ln;

j=fl-1;while(j>=0){if(((bn>>j)&0x1)==0x1){break;lbn=j;}--j;}

j=0;pm=-1;pj=0;
while(j<fl-lbn)
{
	k=0;bf=bn<<j;c=0;m=-1;
	while(k<fl)
	{
		if(((n>>k)&0x1)==0x1){a=1;}else{a=0;}
		if(((bf>>k)&0x1)==0x1){b=1;}else{b=0;}
		if(((a==1)||(b==1))&&(a==b)){++c;}
		++k;
	}	
	if(pm==-1){pm=c;pj=j;}else{if(pm<c){pm=c;pj=j;}}
	++j;
}
if(df){printf("max:\tcnt:%d\tpos:%d\n",pm,pj);}
pm_x=pm;pj_x=pj;
return(pm);
}

int p_mn(int bn , int n , int fl)
{

int i,j,k,m;
int a,b,c;
int bf,pm,pj,lbn=0,ln;

j=fl-1;while(j>=0){if(((bn>>j)&0x1)==0x1){break;lbn=j;}--j;}

j=0;pm=-1;pj=0;
while(j<fl-lbn)
{
	k=0;bf=bn<<j;c=0;m=99;
	while(k<fl)
	{
		if(((n>>k)&0x1)==0x1){a=1;}else{a=0;}
		if(((bf>>k)&0x1)==0x1){b=1;}else{b=0;}
		if(((a==1)||(b==1))&&(a==b)){}else{++c;}
		++k;
	}
	if(pm==-1){pm=c;pj=j;}else{if((pm<c)&&(c>0)){pm=c;pj=j;}}
	++j;
}
if(df){printf("min:\tcnt:%d\tpos:%d\n",pm,pj);}
pm_n=pm;pj_n=pj;
return(pm);
}

int p_1(int n,int fl)
{

int i,j,k,m;
int b_,b1,b2,b3;
int a,b,c;
int mr,md,mx,mn;

//	11110	11111
//	10100	10101
//	01010	01011

b1=(1<<4)|(1<<3)|(1<<2)|(1<<1)|(0<<0);
b2=(1<<4)|(0<<3)|(1<<2)|(0<<1)|(0<<0);
b3=(0<<4)|(1<<3)|(0<<2)|(1<<1)|(0<<0);

mx=p_mx(b1,n,fl);
mn=p_mn(b1,n,fl);

mx=p_mx(b2,n,fl);
mn=p_mn(b2,n,fl);

mx=p_mx(b3,n,fl);
mn=p_mn(b3,n,fl);

return(0);

}

int p_2()
{

int i,j,k,m;
int b1,b2,b3;
int a,b,c;

int n,b_;


int fb[8];
int fbi;

for(i=0;i<256;++i){for(j=0;j<256;++j){for(k=0;k<256;++k){ba[i][j][k][0]=-1;ba[i][j][k][1]=-1;ba[i][j][k][2]=-1;}}}

f1=fopen(fn1,"rb");

while(!feof(f1))
{

//----
	fbi=0;
	fb[0]=fb[1];
	fb[1]=fb[2];
	fb[2]=fb[3];
	fb[3]=fb[4];
	fb[4]=getc(f1);while(fb[4]==10||fb[4]==13){fb[4]=getc(f1);}

	n=0;
	n|=(((int)fb[0])<<8);
	n|=(((int)fb[1])<<0);
	if(df){j=0;while(j<16){if(((n>>j)&0x1)==0x1){printf("1");}else{printf("0");}++j;}printf("\n");}
	p_1(n,16);
	bl_i=0;
	bl_[bl_i]=pm_x;++bl_i;
	bl_[bl_i]=pj_x;++bl_i;
	bl_[bl_i]=pm_n;++bl_i;
	bl_[bl_i]=pj_n;++bl_i;

//----
	fb[0]=fb[1];
	fb[1]=fb[2];
	fb[2]=fb[3];
	fb[3]=fb[4];
	fb[4]=getc(f1);while(fb[4]==10||fb[4]==13){fb[4]=getc(f1);}

	n=0;
	n|=(((int)fb[0])<<8);
	n|=(((int)fb[1])<<0);
	if(df){j=0;while(j<16){if(((n>>j)&0x1)==0x1){printf("1");}else{printf("0");}++j;}printf("\n");}
	p_1(n,16);
	bl_[bl_i]=pm_x;++bl_i;
	bl_[bl_i]=pj_x;++bl_i;
	bl_[bl_i]=pm_n;++bl_i;
	bl_[bl_i]=pj_n;++bl_i;

//----
	fb[0]=fb[1];
	fb[1]=fb[2];
	fb[2]=fb[3];
	fb[3]=fb[4];
	fb[4]=getc(f1);while(fb[4]==10||fb[4]==13){fb[4]=getc(f1);}

	n=0;
	n|=(((int)fb[0])<<8);
	n|=(((int)fb[1])<<0);
	if(df){j=0;while(j<16){if(((n>>j)&0x1)==0x1){printf("1");}else{printf("0");}++j;}printf("\n");}
	p_1(n,16);
	bl_[bl_i]=pm_x;++bl_i;
	bl_[bl_i]=pj_x;++bl_i;
	bl_[bl_i]=pm_n;++bl_i;
	bl_[bl_i]=pj_n;++bl_i;

//----
	fb[0]=fb[1];
	fb[1]=fb[2];
	fb[2]=fb[3];
	fb[3]=fb[4];
	fb[4]=getc(f1);while(fb[4]==10||fb[4]==13){fb[4]=getc(f1);}

	n=0;
	n|=(((int)fb[0])<<8);
	n|=(((int)fb[1])<<0);
	if(df){j=0;while(j<16){if(((n>>j)&0x1)==0x1){printf("1");}else{printf("0");}++j;}printf("\n");}
	p_1(n,16);
	bl_[bl_i]=pm_x;++bl_i;
	bl_[bl_i]=pj_x;++bl_i;
	bl_[bl_i]=pm_n;++bl_i;
	bl_[bl_i]=pj_n;++bl_i;

	if(bli==0)
	{
	bl[bli][0]=bl_[0];
	bl[bli][1]=bl_[1];
	bl[bli][2]=bl_[2];
	bl[bli][3]=bl_[3];
	bl[bli][4]=bl_[4];
	bl[bli][5]=bl_[5];
	bl[bli][6]=bl_[6];
	bl[bli][7]=bl_[7];
	bl[bli][8]=bl_[8];
	bl[bli][9]=bl_[9];
	bl[bli][10]=bl_[10];
	bl[bli][11]=bl_[11];
	bl[bli][12]=bl_[12];
	bl[bli][13]=bl_[13];
	bl[bli][14]=bl_[14];
	bl[bli][15]=bl_[15];
	bl[bli][16]=1;

	bla[bli][0][0]=1;
	if(ba[fb[0]&0xff][fb[1]&0xff][fb[2]&0xff][0]==-1){ba[fb[0]&0xff][fb[1]&0xff][fb[2]&0xff][0]=++ba_1;bla[bli][bla[bli][0][0]][1]=ba_1;}else{bla[bli][bla[bli][0][0]][1]=ba[fb[0]&0xff][fb[1]&0xff][fb[2]&0xff][0];}
	if(ba[fb[1]&0xff][fb[2]&0xff][fb[3]&0xff][1]==-1){ba[fb[1]&0xff][fb[2]&0xff][fb[3]&0xff][1]=++ba_2;bla[bli][bla[bli][0][0]][2]=ba_2;}else{bla[bli][bla[bli][0][0]][2]=ba[fb[1]&0xff][fb[2]&0xff][fb[3]&0xff][1];}
	if(ba[fb[2]&0xff][fb[3]&0xff][fb[4]&0xff][2]==-1){ba[fb[2]&0xff][fb[3]&0xff][fb[4]&0xff][2]=++ba_3;bla[bli][bla[bli][0][0]][3]=ba_3;}else{bla[bli][bla[bli][0][0]][3]=ba[fb[2]&0xff][fb[3]&0xff][fb[4]&0xff][2];}
	
	bl[bli][17]=fb[0];
	bl[bli][18]=fb[1];
	bl[bli][19]=fb[2];
	bl[bli][20]=fb[3];
	bl[bli][21]=fb[4];

	++bli;

	}else{

	for(i=0;i<bli;++i)
	{
		if
		(
		bl[i][0]==bl_[0]&&
		bl[i][1]==bl_[1]&&
		bl[i][2]==bl_[2]&&
		bl[i][3]==bl_[3]&&
		bl[i][4]==bl_[4]&&
		bl[i][5]==bl_[5]&&
		bl[i][6]==bl_[6]&&
		bl[i][7]==bl_[7]&&
		bl[i][8]==bl_[8]&&
		bl[i][9]==bl_[9]&&
		bl[i][10]==bl_[10]&&
		bl[i][11]==bl_[11]&&
		bl[i][12]==bl_[12]&&
		bl[i][13]==bl_[13]&&
		bl[i][14]==bl_[14]&&
		bl[i][15]==bl_[15]
		)
		{
			++bl[i][16];

/*
			if(ba[fb[0]&0xff][fb[1]&0xff][fb[2]&0xff][0]==-1){ba[fb[0]&0xff][fb[1]&0xff][fb[2]&0xff][0]=++ba_1;bla[i][bla[i][0][0]][1]=ba_1;}else{ba_1=ba[fb[0]&0xff][fb[1]&0xff][fb[2]&0xff][0];}
			if(ba[fb[1]&0xff][fb[2]&0xff][fb[3]&0xff][1]==-1){ba[fb[1]&0xff][fb[2]&0xff][fb[3]&0xff][1]=++ba_2;bla[i][bla[i][0][0]][2]=ba_2;}else{ba_2=ba[fb[1]&0xff][fb[2]&0xff][fb[3]&0xff][1];}
			if(ba[fb[2]&0xff][fb[3]&0xff][fb[4]&0xff][2]==-1){ba[fb[2]&0xff][fb[3]&0xff][fb[4]&0xff][2]=++ba_3;bla[i][bla[i][0][0]][3]=ba_3;}else{ba_3=ba[fb[2]&0xff][fb[3]&0xff][fb[4]&0xff][2];}

			for(j=1;j<=bla[i][0][0];++j)
			{
			if
			(
			bla[i][bla[i][0][0]][1]==ba_1&&
			bla[i][bla[i][0][0]][2]==ba_2&&
			bla[i][bla[i][0][0]][3]==ba_3
			){break;}
			}
			if(j==1+bla[i][0][0])
			{
			++bla[i][0][0];
			bla[i][bla[i][0][0]][1]=ba_1;
			bla[i][bla[i][0][0]][2]=ba_2;
			bla[i][bla[i][0][0]][3]=ba_3;
			}
*/

			++bla[i][0][0];
			if(ba[fb[0]&0xff][fb[1]&0xff][fb[2]&0xff][0]==-1){ba[fb[0]&0xff][fb[1]&0xff][fb[2]&0xff][0]=++ba_1;bla[i][bla[i][0][0]][1]=ba_1;}else{bla[i][bla[i][0][0]][1]=ba[fb[0]&0xff][fb[1]&0xff][fb[2]&0xff][0];}
			if(ba[fb[1]&0xff][fb[2]&0xff][fb[3]&0xff][1]==-1){ba[fb[1]&0xff][fb[2]&0xff][fb[3]&0xff][1]=++ba_2;bla[i][bla[i][0][0]][2]=ba_2;}else{bla[i][bla[i][0][0]][2]=ba[fb[1]&0xff][fb[2]&0xff][fb[3]&0xff][1];}
			if(ba[fb[2]&0xff][fb[3]&0xff][fb[4]&0xff][2]==-1){ba[fb[2]&0xff][fb[3]&0xff][fb[4]&0xff][2]=++ba_3;bla[i][bla[i][0][0]][3]=ba_3;}else{bla[i][bla[i][0][0]][3]=ba[fb[2]&0xff][fb[3]&0xff][fb[4]&0xff][2];}

			break;
		}
	}

	if(i==bli)
	{
		bl[bli][0]=bl_[0];
		bl[bli][1]=bl_[1];
		bl[bli][2]=bl_[2];
		bl[bli][3]=bl_[3];
		bl[bli][4]=bl_[4];
		bl[bli][5]=bl_[5];
		bl[bli][6]=bl_[6];
		bl[bli][7]=bl_[7];
		bl[bli][8]=bl_[8];
		bl[bli][9]=bl_[9];
		bl[bli][10]=bl_[10];
		bl[bli][11]=bl_[11];
		bl[bli][12]=bl_[12];
		bl[bli][13]=bl_[13];
		bl[bli][14]=bl_[14];
		bl[bli][15]=bl_[15];
		bl[bli][16]=1;

		bla[bli][0][0]=1;
		if(ba[fb[0]&0xff][fb[1]&0xff][fb[2]&0xff][0]==-1){ba[fb[0]&0xff][fb[1]&0xff][fb[2]&0xff][0]=++ba_1;bla[bli][bla[bli][0][0]][1]=ba_1;}else{bla[bli][bla[bli][0][0]][1]=ba[fb[0]&0xff][fb[1]&0xff][fb[2]&0xff][0];}
		if(ba[fb[1]&0xff][fb[2]&0xff][fb[3]&0xff][1]==-1){ba[fb[1]&0xff][fb[2]&0xff][fb[3]&0xff][1]=++ba_2;bla[bli][bla[bli][0][0]][2]=ba_2;}else{bla[bli][bla[bli][0][0]][2]=ba[fb[1]&0xff][fb[2]&0xff][fb[3]&0xff][1];}
		if(ba[fb[2]&0xff][fb[3]&0xff][fb[4]&0xff][2]==-1){ba[fb[2]&0xff][fb[3]&0xff][fb[4]&0xff][2]=++ba_3;bla[bli][bla[bli][0][0]][3]=ba_3;}else{bla[bli][bla[bli][0][0]][3]=ba[fb[2]&0xff][fb[3]&0xff][fb[4]&0xff][2];}

		bl[bli][17]=fb[0];
		bl[bli][18]=fb[1];
		bl[bli][19]=fb[2];
		bl[bli][20]=fb[3];
		bl[bli][21]=fb[4];
		++bli;
	}
	}

}
fclose(f1);

f1=fopen(ofn1,"w");
for(i=0;i<bli;++i)
{

	fprintf(f1,"%02d",bl[i][0]);
	fprintf(f1,"%02d",bl[i][1]);
	fprintf(f1,"%02d",bl[i][2]);
	fprintf(f1,"%02d",bl[i][3]);
	fprintf(f1,"\t");
	fprintf(f1,"%02d",bl[i][4]);
	fprintf(f1,"%02d",bl[i][5]);
	fprintf(f1,"%02d",bl[i][6]);
	fprintf(f1,"%02d",bl[i][7]);
	fprintf(f1,"\t");
	fprintf(f1,"%02d",bl[i][8]);
	fprintf(f1,"%02d",bl[i][9]);
	fprintf(f1,"%02d",bl[i][10]);
	fprintf(f1,"%02d",bl[i][11]);
	fprintf(f1,"\t");
	fprintf(f1,"%02d",bl[i][12]);
	fprintf(f1,"%02d",bl[i][13]);
	fprintf(f1,"%02d",bl[i][14]);
	fprintf(f1,"%02d",bl[i][15]);
	fprintf(f1,"\t");
	fprintf(f1,"%d",bl[i][16]);
	fprintf(f1,"\t");
	fprintf(f1,"%c%c%c%c%c\n",bl[i][17],bl[i][18],bl[i][19],bl[i][20],bl[i][21]);

}
fclose(f1);

for(i=0;i<10000;++i){ca[i][0][0]=-1;ca[i][1][0]=-1;ca[i][2][0]=-1;}

for(b1=0;b1<256;++b1){for(b2=0;b2<256;++b2){for(b3=0;b3<256;++b3){

if(ba[b1][b2][b3][0]!=-1)
{
ca[ba[b1][b2][b3][0]][0][0]=b1;
ca[ba[b1][b2][b3][0]][0][1]=b2;
ca[ba[b1][b2][b3][0]][0][2]=b3;
}
if(ba[b1][b2][b3][1]!=-1)
{
ca[ba[b1][b2][b3][1]][1][0]=b1;
ca[ba[b1][b2][b3][1]][1][1]=b2;
ca[ba[b1][b2][b3][1]][1][2]=b3;
}
if(ba[b1][b2][b3][2]!=-1)
{
ca[ba[b1][b2][b3][0]][2][0]=b1;
ca[ba[b1][b2][b3][0]][2][1]=b2;
ca[ba[b1][b2][b3][0]][2][2]=b3;
}

}}}

f1=fopen(ofn2,"w");
f2=fopen(ofn3,"w");
for(i=0;i<bli;++i)
{

for(j=1;j<=bla[i][0][0];++j)
{
//--------------------------------
//for(b1=0;b1<256;++b1){for(b2=0;b2<256;++b2){for(b3=0;b3<256;++b3){if(bla[i][j][1]==ba[b1][b2][b3][0]){break;}}if(b3<256){break;}}if(b2<256){break;}}

//12-2-23

if(ca[bla[i][j][1]][0][0]!=1)
{
if(bl[i][17]==ca[bla[i][j][1]][0][0]){fprintf(f1,"%c",(char)ca[bla[i][j][1]][0][0]);}else{fprintf(f1,"_");}
if(bl[i][18]==ca[bla[i][j][1]][0][1]){fprintf(f1,"%c",(char)ca[bla[i][j][1]][0][1]);}else{fprintf(f1,"_");}
}

//1-12-23

if(ca[bla[i][j][1]][0][0]!=-1)
{
if(bl[i][17]==ca[bla[i][j][1]][0][0]){fprintf(f2,"%c",(char)ca[bla[i][j][1]][0][0]);}else{fprintf(f2,"_");}
}

//--------------------------------
//for(b1=0;b1<256;++b1){for(b2=0;b2<256;++b2){for(b3=0;b3<256;++b3){if(bla[i][j][2]==ba[b1][b2][b3][1]){break;}}if(b3<256){break;}}if(b2<256){break;}}

//12-2-23

if(ca[bla[i][j][2]][1][0]!=-1)
{
if(bl[i][19]==ca[bla[i][j][2]][1][1]){fprintf(f1,"%c",(char)ca[bla[i][j][2]][1][1]);}else{fprintf(f1,"_");}
}

//1-12-23

if(ca[bla[i][j][2]][1][0]!=-1)
{
if(bl[i][18]==ca[bla[i][j][2]][1][0]){fprintf(f2,"%c",(char)ca[bla[i][j][2]][1][0]);}else{fprintf(f2,"_");}
if(bl[i][19]==ca[bla[i][j][2]][1][1]){fprintf(f2,"%c",(char)ca[bla[i][j][2]][1][1]);}else{fprintf(f2,"_");}
}

//--------------------------------
//for(b1=0;b1<256;++b1){for(b2=0;b2<256;++b2){for(b3=0;b3<256;++b3){if(bla[i][j][3]==ba[b1][b2][b3][2]){break;}}if(b3<256){break;}}if(b2<256){break;}}

//12-2-23

if(ca[bla[i][j][3]][2][0]!=-1)
{
if(bl[i][20]==ca[bla[i][j][3]][2][1]){fprintf(f1,"%c",(char)ca[bla[i][j][3]][2][1]);}else{fprintf(f1,"_");}
if(bl[i][21]==ca[bla[i][j][3]][2][2]){fprintf(f1,"%c",(char)ca[bla[i][j][3]][2][2]);}else{fprintf(f1,"_");}
}

//1-12-23

if(ca[bla[i][j][3]][2][0]!=-1)
{
if(bl[i][20]==ca[bla[i][j][3]][2][1]){fprintf(f2,"%c",(char)ca[bla[i][j][3]][2][1]);}else{fprintf(f2,"_");}
if(bl[i][21]==ca[bla[i][j][3]][2][2]){fprintf(f2,"%c",(char)ca[bla[i][j][3]][2][2]);}else{fprintf(f2,"_");}
}
//--------------------------------
fprintf(f1,"\t");
fprintf(f1,"%c%c%c%c%c\n",bl[i][17],bl[i][18],bl[i][19],bl[i][20],bl[i][21]);
fprintf(f2,"\t");
fprintf(f2,"%c%c%c%c%c\n",bl[i][17],bl[i][18],bl[i][19],bl[i][20],bl[i][21]);
//--------------------------------
}

}
fclose(f1);
	
return(0);
}

int main()
{
	p_2();
	return(0);
}