//	This source and bit parity similar text sequences method apply to GNU General Public License. 
//			Copyright (C) 2001-2012 , 2015 Jasenko Dzinleski 

//		This program is free software; you can redistribute it
//	and/or modify it under the terms of the GNU General Public License as
//	published by the Free Software Foundation; either version 2 of the
//	License, or (at your option) any later version. 

//	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.

//  	Bit Parity Similar Text Sequences	
//	written by Dzinleski Jasenko  November 2015


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

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

char		infn[256]="War_and_Peace_NT.txt";

int 		ba[16][16][16][16][2][2];	
int 		ba0i=0;	
int 		ba1i=0;
int 		dba[256][256][3];

int		bt32_1[32];	int	bt32i_1=0;
int		bt32_2[32];	int	bt32i_2=0;
int		nL[1000][100];	int 	cn=0;

int main()
{

	int fbyteH,fbyteL;
	int b8e,b8o;
	int i,j,k,l;
	int i1,j1,k1,l1;	
	int t1,t2,t3;
	int ti1,tj1,tk1,tl1;
			
	//10101010
	b8e=0;		
	b8e|=1<<1;
	b8e|=1<<3;
	b8e|=1<<5;
	b8e|=1<<7;
	
	//01010101
	b8o=0;		
	b8o|=1<<0;
	b8o|=1<<2;
	b8o|=1<<4;
	b8o|=1<<6;

	for(i=0;i<16;++i){for(j=0;j<16;++j){for(k=0;k<16;++k){for(l=0;l<16;++l){
				ba[i][j][k][l][0][0]=-1;ba[i][j][k][l][0][1]=0;
				ba[i][j][k][l][1][0]=-1;ba[i][j][k][l][1][1]=0;
	}}}}
	for(i=0;i<256;++i){for(j=0;j<256;++j){dba[i][j][0]=-1;dba[i][j][1]=-1;dba[i][j][2]=0;}}
	for(i=0;i<1000;++i){nL[i][0]=-1;}
			
	f1=fopen(infn,"rb");

	fbyteH=getc(f1);
	fbyteL=getc(f1);
	while(!feof(f1))
	{		
		if
		(
		ba[((fbyteH&b8e)>>4)&0xf][((fbyteH&b8o)>>4)&0xf][((fbyteL&b8e)>>4)&0xf][((fbyteL&b8o)>>4)&0xf][0][0]==-1
		)
		{
			ba[((fbyteH&b8e)>>4)&0xf][((fbyteH&b8o)>>4)&0xf][((fbyteL&b8e)>>4)&0xf][((fbyteL&b8o)>>4)&0xf][0][0]=ba0i;++ba0i;
			ba[((fbyteH&b8e)>>4)&0xf][((fbyteH&b8o)>>4)&0xf][((fbyteL&b8e)>>4)&0xf][((fbyteL&b8o)>>4)&0xf][0][1]=1;
		}else{
				++ba[((fbyteH&b8e)>>4)&0xf][((fbyteH&b8o)>>4)&0xf][((fbyteL&b8e)>>4)&0xf][((fbyteL&b8o)>>4)&0xf][0][1];
		}		
		if
		(
		ba[((fbyteH&b8e))&0xf][((fbyteH&b8o))&0xf][((fbyteL&b8e))&0xf][((fbyteL&b8o))&0xf][1][0]==-1
		)
		{
			ba[((fbyteH&b8e))&0xf][((fbyteH&b8o))&0xf][((fbyteL&b8e))&0xf][((fbyteL&b8o))&0xf][1][0]=ba1i;++ba1i;
			ba[((fbyteH&b8e))&0xf][((fbyteH&b8o))&0xf][((fbyteL&b8e))&0xf][((fbyteL&b8o))&0xf][1][1]=1;
		}else{
				++ba[((fbyteH&b8e))&0xf][((fbyteH&b8o))&0xf][((fbyteL&b8e))&0xf][((fbyteL&b8o))&0xf][1][1];
		}
		if
		(
		dba[fbyteH][fbyteL][0]==-1
		)
		{
			dba[fbyteH][fbyteL][0]=ba[((fbyteH&b8e)>>4)&0xf][((fbyteH&b8o)>>4)&0xf][((fbyteL&b8e)>>4)&0xf][((fbyteL&b8o)>>4)&0xf][0][0];
			dba[fbyteH][fbyteL][1]=ba[((fbyteH&b8e))&0xf][((fbyteH&b8o))&0xf][((fbyteL&b8e))&0xf][((fbyteL&b8o))&0xf][1][0];
			dba[fbyteH][fbyteL][2]=1;
		}else{++dba[fbyteH][fbyteL][2];}
				
		fbyteH=fbyteL;
		fbyteL=getc(f1);		
	}
	fclose(f1);
	printf("%d %d\n",ba0i,ba1i);
	
	for(t1=0;t1<256;++t1){for(t2=0;t2<256;++t2){
		if(dba[t1][t2][0]!=-1)
		{
				printf("%c%c\t",t1,t2);
				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(ba[i][j][k][l][0][0]==dba[t1][t2][0]&&ba[i][j][k][l][1][0]!=-1)
				{
					printf("H\t%d\t",ba[i][j][k][l][0][1]);
					for(i1=0;i1<16;++i1){for(j1=0;j1<16;++j1){for(k1=0;k1<16;++k1){for(l1=0;l1<16;++l1){
						if(ba[i1][j1][k1][l1][1][0]==dba[t1][t2][1])
						{
							printf("L\t%d\t",ba[i1][j1][k1][l1][1][1]);
							printf("%c%c\t",(((i|j)<<4)|(i1|j1)),(((k|l)<<4)|(k1|l1)));
							if(cn==0)
							{
								nL[cn][0]=ba[i1][j1][k1][l1][1][1];
								nL[cn][1]=2;
								nL[cn][nL[cn][1]]=((((i|j)<<4)|(i1|j1))<<8)|(((k|l)<<4)|(k1|l1));++cn;
							}else{
								for(t3=0;t3<cn;++t3)
								{
									if(nL[t3][0]==ba[i1][j1][k1][l1][1][1])
									{
										++nL[t3][1];
										nL[t3][nL[t3][1]]=((((i|j)<<4)|(i1|j1))<<8)|(((k|l)<<4)|(k1|l1));		
										break;
									}
								}
								if(t3==cn)
								{
									nL[cn][0]=ba[i1][j1][k1][l1][1][1];
									nL[cn][1]=2;
									nL[cn][nL[cn][1]]=((((i|j)<<4)|(i1|j1))<<8)|(((k|l)<<4)|(k1|l1));++cn;
								}
							}
						}
					}}}}
				}
				}}}}				
				printf("%d\n",dba[t1][t2][2]);
		}
	}}	
	printf("nL %d\n",cn);
	for(t1=0;t1<cn;++t1){
		printf("%d\t",nL[t1][0]);
		for(t2=2;t2<=nL[t1][1];++t2){
		printf("%c%c\t",((nL[t1][t2]&0xff00)>>8),(nL[t1][t2]&0x00ff));
	}printf("\n");}	
	return(0);
	
}