//      This source and Arbitrary Lengths of Text Sequences method apply to GNU General Public License. 
//                      Copyright (C) 2013  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 - 2012 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.

//
//                      Arbitrary Lengths of Text Sequences
//                      written by Dzinleski Jasenko April , 2013
//


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

FILE	*f1,*f2;

char	infn[256]="fasta_32.txt";
char	outfn[256]="out.txt";

int 	ba1[16][16][16][16][2];	int ba1i=0;
int 	ba_[4][4][4][4][2];		int ba_i=0;
int 	ba2[16][16][16][16][2];	int ba2i=0;
char	lb[256];				int	lbi=0;

int main(int argc,char *argv[])
{

	int	a,b,c,d=0,e;
	int	i,j,k,l,m;
	int	i_,j_,k_,l_;
	int	fbyte1,fbyte2,fbyte3;

	int	b16o,b16e;
	int	b1,b2,b3,b1_,b2_,b3_,d1,d2,d3;
	int	lcnt=0,ll,lc;
		
	for(i=0;i<16;++i){for(j=0;j<16;++j){for(k=0;k<16;++k){for(l=0;l<16;++l){
		ba1[i][j][k][l][0]=-1;ba1[i][j][k][l][1]=0;
		ba2[i][j][k][l][0]=-1;ba2[i][j][k][l][1]=0;
	}}}}

	for(i=0;i<4;++i){for(j=0;j<4;++j){for(k=0;k<4;++k){for(l=0;l<4;++l){	
		ba_[i][j][k][l][0]=-1;
		ba_[i][j][k][l][1]=0;
	}}}}
	
	f1=fopen(infn,"rb");

	fbyte1=getc(f1);
	fbyte2=getc(f1);
	fbyte3=getc(f1);
	while(!feof(f1))
	{
		if(ba1[(((fbyte1<<8)|fbyte2)&0xf000)>>12][(((fbyte1<<8)|fbyte2)&0x0f00)>>8][(((fbyte1<<8)|fbyte2)&0x00f0)>>4][(((fbyte1<<8)|fbyte2)&0x000f)>>0][0]==-1)
		{
			ba1[(((fbyte1<<8)|fbyte2)&0xf000)>>12][(((fbyte1<<8)|fbyte2)&0x0f00)>>8][(((fbyte1<<8)|fbyte2)&0x00f0)>>4][(((fbyte1<<8)|fbyte2)&0x000f)>>0][0]=ba1i;
			++ba1i;
			ba1[(((fbyte1<<8)|fbyte2)&0xf000)>>12][(((fbyte1<<8)|fbyte2)&0x0f00)>>8][(((fbyte1<<8)|fbyte2)&0x00f0)>>4][(((fbyte1<<8)|fbyte2)&0x000f)>>0][1]=1;
		}else{
			++ba1[(((fbyte1<<8)|fbyte2)&0xf000)>>12][(((fbyte1<<8)|fbyte2)&0x0f00)>>8][(((fbyte1<<8)|fbyte2)&0x00f0)>>4][(((fbyte1<<8)|fbyte2)&0x000f)>>0][1];
		}
		
		if(ba2[(((fbyte2<<8)|fbyte3)&0xf000)>>12][(((fbyte2<<8)|fbyte3)&0x0f00)>>8][(((fbyte2<<8)|fbyte3)&0x00f0)>>4][(((fbyte2<<8)|fbyte3)&0x000f)>>0][0]==-1)
		{
			ba2[(((fbyte2<<8)|fbyte3)&0xf000)>>12][(((fbyte2<<8)|fbyte3)&0x0f00)>>8][(((fbyte2<<8)|fbyte3)&0x00f0)>>4][(((fbyte2<<8)|fbyte3)&0x000f)>>0][0]=ba2i;
			++ba2i;
			ba2[(((fbyte2<<8)|fbyte3)&0xf000)>>12][(((fbyte2<<8)|fbyte3)&0x0f00)>>8][(((fbyte2<<8)|fbyte3)&0x00f0)>>4][(((fbyte2<<8)|fbyte3)&0x000f)>>0][1]=1;
		}else{
			++ba2[(((fbyte2<<8)|fbyte3)&0xf000)>>12][(((fbyte2<<8)|fbyte3)&0x0f00)>>8][(((fbyte2<<8)|fbyte3)&0x00f0)>>4][(((fbyte2<<8)|fbyte3)&0x000f)>>0][1];
		}
		
		if(ba_[(((fbyte2&0xf0)>>4)>>2)&0x3][((fbyte2&0xf0)>>4)&0x3][((fbyte2&0x0f)>>2)&0x3][(fbyte2&0x0f)&0x3][0]==-1)
		{
			ba_[(((fbyte2&0xf0)>>4)>>2)&0x3][((fbyte2&0xf0)>>4)&0x3][((fbyte2&0x0f)>>2)&0x3][(fbyte2&0x0f)&0x3][0]=ba_i;
			++ba_i;
			ba_[(((fbyte2&0xf0)>>4)>>2)&0x3][((fbyte2&0xf0)>>4)&0x3][((fbyte2&0x0f)>>2)&0x3][(fbyte2&0x0f)&0x3][1]=1;
		}else{
			++ba_[(((fbyte2&0xf0)>>4)>>2)&0x3][((fbyte2&0xf0)>>4)&0x3][((fbyte2&0x0f)>>2)&0x3][(fbyte2&0x0f)&0x3][1];
		}		
		
		fbyte1=fbyte2;
		fbyte2=fbyte3;
		fbyte3=getc(f1);
		fbyte3=getc(f1);while((fbyte3==10)||(fbyte3==13)){fbyte3=getc(f1);}		
		
	}
	fclose(f1);
	
	printf("%d %d %d\n",ba1i,ba2i,ba_i);
	
	m=1;a=1;
	while(m!=-1)
	{
	m=-1;
	for(i=0;i<16;++i){for(j=0;j<16;++j){for(k=0;k<16;++k){for(l=0;l<16;++l){
	
		if(ba1[i][j][k][l][1]>=1)
		{
			if(m==-1){m=ba1[i][j][k][l][1];i_=i;j_=j;k_=k;l_=l;}else{
				if(m<ba1[i][j][k][l][1]){m=ba1[i][j][k][l][1];i_=i;j_=j;k_=k;l_=l;}
			}
		}

	}}}}
	
	if(m!=-1){ba1[i_][j_][k_][l_][0]=a;ba1[i_][j_][k_][l_][1]=0;a+=2;}
	
	}
	printf("%d\t",a);
	
	m=1;a=1;
	while(m!=-1)
	{
	m=-1;
	for(i=0;i<16;++i){for(j=0;j<16;++j){for(k=0;k<16;++k){for(l=0;l<16;++l){
	
		if(ba2[i][j][k][l][1]>=1)
		{
			if(m==-1){m=ba2[i][j][k][l][1];i_=i;j_=j;k_=k;l_=l;}else{
				if(m<ba2[i][j][k][l][1]){m=ba2[i][j][k][l][1];i_=i;j_=j;k_=k;l_=l;}
			}
		}

	}}}}
	
	if(m!=-1){ba2[i_][j_][k_][l_][0]=a;ba2[i_][j_][k_][l_][1]=0;a+=2;}
	
	}
	printf("%d\t",a);
	
	m=1;a=1;
	while(m!=-1)
	{
	m=-1;
	for(i=0;i<4;++i){for(j=0;j<4;++j){for(k=0;k<4;++k){for(l=0;l<4;++l){
	
		if(ba_[i][j][k][l][1]>=1)
		{
			if(m==-1){m=ba_[i][j][k][l][1];i_=i;j_=j;k_=k;l_=l;}else{
				if(m<ba_[i][j][k][l][1]){m=ba_[i][j][k][l][1];i_=i;j_=j;k_=k;l_=l;}
			}
		}

	}}}}
	
	if(m!=-1){ba_[i_][j_][k_][l_][0]=a;ba_[i_][j_][k_][l_][1]=0;a+=2;}
	
	}	
	printf("%d\n",a);
	
	//return(0);
		
	b16o=0;
	b16o|=1<<0;
	b16o|=1<<2;
	b16o|=1<<4;
	b16o|=1<<6;
	b16o|=1<<8;
	b16o|=1<<10;
	b16o|=1<<12;
	b16o|=1<<14;
	
	b16e=0;
	b16e|=1<<1;
	b16e|=1<<3;
	b16e|=1<<5;
	b16e|=1<<7;
	b16e|=1<<9;
	b16e|=1<<11;
	b16e|=1<<13;
	b16e|=1<<15;
	
	a=0;b=0;c=0;l=-1;ll=-1;lc=0;
	f1=fopen(infn,"rb");
	f2=fopen(outfn,"w");

	for(i=0;i<256;++i){lb[i]='\0';}lbi=0;
	
	fbyte1=getc(f1);lb[lbi]=fbyte1;++lbi;
	fbyte2=getc(f1);lb[lbi]=fbyte2;++lbi;
	fbyte3=getc(f1);lb[lbi]=fbyte3;++lbi;
	while(!feof(f1))
	{
	
		b1_=ba1[(((fbyte1<<8)|fbyte2)&0xf000)>>12][(((fbyte1<<8)|fbyte2)&0x0f00)>>8][(((fbyte1<<8)|fbyte2)&0x00f0)>>4][(((fbyte1<<8)|fbyte2)&0x000f)>>0][0]<<1;
		b2_=ba_[(((fbyte2&0xf0)>>4)>>2)&0x3][((fbyte2&0xf0)>>4)&0x3][((fbyte2&0x0f)>>2)&0x3][(fbyte2&0x0f)&0x3][0]<<1;
		b3_=ba2[(((fbyte1<<8)|fbyte2)&0xf000)>>12][(((fbyte1<<8)|fbyte2)&0x0f00)>>8][(((fbyte1<<8)|fbyte2)&0x00f0)>>4][(((fbyte1<<8)|fbyte2)&0x000f)>>0][0]<<1;
		
		d1=((((b1_&b16e)>>1)^(b2_&b16o))|((b1_&b16e)^((b2_&b16o)<<1)));	
		d2=((((b2_&b16e)>>1)^(b3_&b16o))|((b2_&b16e)^((b3_&b16o)<<1)));
		d3=((((b1_&b16e)>>1)^(b3_&b16o))|((b1_&b16e)^((b3_&b16o)<<1)));
		
		if(d1==d2){++a;if(d2==d3){++c;}}
		if((d1!=d2)&&(d2!=d3)){++d;}

		if((d1==d2)||(d2==d3))
		{
		
			fbyte1=getc(f1);i=0;while((fbyte1==10)||(fbyte1==13)){++i;fbyte1=getc(f1);}		
			lb[lbi]=fbyte1;++lbi;
			if(i!=0)
			{
				++lcnt;
				lb[lbi-1]='\0';
				j=0;k=-1;
				for(i=0;i<256;++i){
					if(lb[i]!='_'){++j;}else{
						if(k==-1){k=j;}else{if(k<j){k=j;}}
						j=1;
					}
				}lbi=0;
				if(k==-1){k=0;}fprintf(f2,"%d\t%s\t%d\n",lcnt,lb,k);
				for(i=0;i<256;++i){lb[i]='\0';}lbi=0;			
				lb[lbi]=fbyte1;++lbi;
			}
			
			fbyte2=getc(f1);i=0;while((fbyte2==10)||(fbyte2==13)){++i;fbyte2=getc(f1);}		
			lb[lbi]=fbyte2;++lbi;
			if(i!=0)
			{
				++lcnt;
				lb[lbi-1]='\0';
				j=0;k=-1;
				for(i=0;i<256;++i){
					if(lb[i]!='_'){++j;}else{
						if(k==-1){k=j;}else{if(k<j){k=j;}}
						j=1;
					}
				}lbi=0;
				if(k==-1){k=0;}fprintf(f2,"%d\t%s\t%d\n",lcnt,lb,k);
				for(i=0;i<256;++i){lb[i]='\0';}lbi=0;			
				lb[lbi]=fbyte2;++lbi;
			}
			
			fbyte3=getc(f1);i=0;while((fbyte3==10)||(fbyte3==13)){++i;fbyte3=getc(f1);}		
			lb[lbi]=fbyte3;++lbi;
			if(i!=0)
			{
				++lcnt;
				lb[lbi-1]='\0';
				j=0;k=-1;
				for(i=0;i<256;++i){
					if(lb[i]!='_'){++j;}else{
						if(k==-1){k=j;}else{if(k<j){k=j;}}
						j=1;
					}
				}lbi=0;
				if(k==-1){k=0;}fprintf(f2,"%d\t%s\t%d\n",lcnt,lb,k);
				for(i=0;i<256;++i){lb[i]='\0';}lbi=0;			
				lb[lbi]=fbyte3;++lbi;				
			}
			
		}else{
		
			lb[lbi-3]='_';
			fbyte1=fbyte2;
			fbyte2=fbyte3;
			fbyte3=getc(f1);i=0;while((fbyte3==10)||(fbyte3==13)){++i;fbyte3=getc(f1);}		
			lb[lbi]=fbyte3;++lbi;
		
			if(i!=0)
			{
				++lcnt;
				lb[lbi-1]='\0';
				j=0;k=-1;
				for(i=0;i<256;++i){
					if(lb[i]!='_'){++j;}else{
						if(k==-1){k=j;}else{if(k<j){k=j;}}
						j=1;
					}
				}lbi=0;
				if(k==-1){k=0;}fprintf(f2,"%d\t%s\t%d\n",lcnt,lb,k);
				for(i=0;i<256;++i){lb[i]='\0';}lbi=0;			
				lb[lbi]=fbyte3;++lbi;
			}			
		}

		//printf("%d %d %d\n",d1,d2,d3);
		//printf("%d %d %d\n",d1,d2,d3);
		

		
	}
	fclose(f1);
	//printf("%d %d %e\n",a,c,100.00-100.00*((double)c/(double)a));
	printf("%d %d %d\n",a,c,d);
	
	return(0);

}