//	This source and Compression , Enthropy quotioent 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 - 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.

//
//		Enthropy quotioent
//		written by Dzinleski Jasenko  October , 2013
//

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

FILE	*f1;

char	infn[256]="War_and_Peace_NT.txt";
int 	ba2b[256][256][50][4];	int ba2bi=0;
int		df=0;
int		e;
char	pa[9];
int		ea[256];		int	eai=0;
char	sa[256];		int sai=0;

int p_n(int b1_,int b2_,int b3_)
{

int	b1,b2,b3;
int	i,j,k,l;
int	p;
int	s1,s21,s22,s23;
int	a1[9];int a1i;
int	s;
int	t;
int	a=0;
char	da[10];

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

  s1=1;

  s21=0;
//s21|=1<<0;
  s21|=1<<1;
//s21|=1<<2;
  s21|=1<<3;
//s21|=1<<4;

  s22=0;
//s22|=1<<0;
//s22|=1<<1;
  s22|=1<<2;
//s22|=1<<3;
  s22|=1<<4;

  s23=0;
//s23|=1<<0;
  s23|=1<<1;
  s23|=1<<2;
  s23|=1<<3;
  s23|=1<<4;

t=b3_;

a1[0]=1;
a1[1]=2;
a1[2]=1;

a1[3]=1;
a1[4]=4;
a1[5]=1;

a1[6]=1;
a1[7]=2;
a1[8]=1;

s=1;j=1;a=0;
for(i=0;i<256;i+=s)
{
    ++a;
	b3_=i;

	if(df==1){printf("%d\t%d\t%d\n",i,s,a);}
	
	if((((t-b3_)>=-4)&&((t-b3_)<=4)))
	{
		da[0]=a1[0]+48;
		da[1]=a1[1]+48;
		da[2]=a1[2]+48;
		da[3]=a1[3]+48;
		da[4]=a1[4]+48;
		da[5]=a1[5]+48;
		da[6]=a1[6]+48;
		da[7]=a1[7]+48;
		da[8]=a1[8]+48;
		break;
	}

	if(a1[j]==1){s=s1;++j;if(!(j<9)){j=1;}continue;}
	if(a1[j]==2){s=s21;++j;if(!(j<9)){j=1;}continue;}
	if(a1[j]==3){s=s22;++j;if(!(j<9)){j=1;}continue;}
	if(a1[j]==4){s=s23;++j;if(!(j<9)){j=1;}continue;}
	
}

l=0;
while(!(((t-b3_)>=-4)&&((t-b3_)<=4))&&l<9-1)
{

k=a1[0];
a1[0]=a1[1];
a1[1]=a1[2];
a1[2]=a1[3];
a1[3]=a1[4];
a1[4]=a1[5];
a1[5]=a1[6];
a1[6]=a1[7];
a1[7]=a1[8];
a1[8]=k;

s=1;j=1;a=0;
for(i=0;i<256;i+=s)
{
    ++a;
	b3_=i;

	if(df==1){printf("%d\t%d\t%d\n",i,s,a);}
	
	if((((t-b3_)>=-4)&&((t-b3_)<=4)))
	{
		da[0]=a1[0]+48;
		da[1]=a1[1]+48;
		da[2]=a1[2]+48;
		da[3]=a1[3]+48;
		da[4]=a1[4]+48;
		da[5]=a1[5]+48;
		da[6]=a1[6]+48;
		da[7]=a1[7]+48;
		da[8]=a1[8]+48;
		break;
	}

	if(a1[j]==1){s=s1;++j;if(!(j<9)){j=1;}continue;}
	if(a1[j]==2){s=s21;++j;if(!(j<9)){j=1;}continue;}
	if(a1[j]==3){s=s22;++j;if(!(j<9)){j=1;}continue;}
	if(a1[j]==4){s=s23;++j;if(!(j<9)){j=1;}continue;}
	
}
if((((t-b3_)>=-4)&&((t-b3_)<=4))){break;}

++l;
}
if(!(((t-b3_)>=-4)&&((t-b3_)<=4))){++e;return(-1);}

if(df==1){
printf("\n%d %d %e\n\n",e,a,100.00-100.00*((double)e/(double)a));
}

//printf("\n%c%c%c%c%c%c%c%c%c\n",da[0],da[1],da[2],da[3],da[4],da[5],da[6],da[7],da[8]);
//printf(".%d.\n",t-b3_);

pa[0]=da[0];pa[1]=da[1];pa[2]=da[2];pa[3]=da[3];pa[4]=da[4];pa[5]=da[5];pa[6]=da[6];pa[7]=da[7];pa[8]=da[8];

e=t-b3_;return(a);

}

int p_r(int b1_,int b2_,int a,int o,int c)
{

int	i,j,k,l;
int	p;
int	s1,s21,s22,s23;
int	a1[9];int a1i;
int	s;
int	t;
int	b=0;

if(((o>>16)&0x3)==1){a1[0]=1;}
if(((o>>16)&0x3)==2){a1[0]=2;}
if(((o>>16)&0x3)==3){a1[0]=4;}

if(((o>>14)&0x3)==1){a1[1]=1;}
if(((o>>14)&0x3)==2){a1[1]=2;}
if(((o>>14)&0x3)==3){a1[1]=4;}

if(((o>>12)&0x3)==1){a1[2]=1;}
if(((o>>12)&0x3)==2){a1[2]=2;}
if(((o>>12)&0x3)==3){a1[2]=4;}

if(((o>>10)&0x3)==1){a1[3]=1;}
if(((o>>10)&0x3)==2){a1[3]=2;}
if(((o>>10)&0x3)==3){a1[3]=4;}

if(((o>>8)&0x3)==1){a1[4]=1;}
if(((o>>8)&0x3)==2){a1[4]=2;}
if(((o>>8)&0x3)==3){a1[4]=4;}

if(((o>>6)&0x3)==1){a1[5]=1;}
if(((o>>6)&0x3)==2){a1[5]=2;}
if(((o>>6)&0x3)==3){a1[5]=4;}

if(((o>>4)&0x3)==1){a1[6]=1;}
if(((o>>4)&0x3)==2){a1[6]=2;}
if(((o>>4)&0x3)==3){a1[6]=4;}

if(((o>>2)&0x3)==1){a1[7]=1;}
if(((o>>2)&0x3)==2){a1[7]=2;}
if(((o>>2)&0x3)==3){a1[7]=4;}

if(((o>>0)&0x3)==1){a1[8]=1;}
if(((o>>0)&0x3)==2){a1[8]=2;}
if(((o>>0)&0x3)==3){a1[8]=4;}

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

  s1=1;

  s21=0;
//s21|=1<<0;
  s21|=1<<1;
//s21|=1<<2;
  s21|=1<<3;
//s21|=1<<4;

  s22=0;
//s22|=1<<0;
//s22|=1<<1;
  s22|=1<<2;
//s22|=1<<3;
  s22|=1<<4;

  s23=0;
//s23|=1<<0;
  s23|=1<<1;
  s23|=1<<2;
  s23|=1<<3;
  s23|=1<<4;

s=1;j=1;b=0;
for(i=0;i<256&&b<a-1;i+=s)
{
    ++b;
	//printf("%d\t%d\t%d\t%d\n",i,s,b,a);
	if(a1[j]==1){s=s1;++j;if(!(j<9)){j=1;}continue;}
	if(a1[j]==2){s=s21;++j;if(!(j<9)){j=1;}continue;}
	if(a1[j]==3){s=s22;++j;if(!(j<9)){j=1;}continue;}
	if(a1[j]==4){s=s23;++j;if(!(j<9)){j=1;}continue;}
}

sa[sai]=i+ea[c];++sai;

return(i+ea[c]);

}

int main(int argc,char *argv[])
{
int	a,b,c,d;
int	i,j,k,l,m,n,o,r;

int	b1_,b1__,b2_,b2__,b3_,b3__;

int	mc=0,unmc=0;
long	pos;

int	fbyte;
char	nl[256];int nli=0;

	printf("\n\tEnthropy quotioent\n");
	printf("\twritten by Dzinleski Jasenko October , 2013\n");

	if(argv[1]==NULL){return(0);}else{
		strcpy(infn,argv[1]);f1=fopen(infn,"rb");
		if(f1==NULL){return(0);}else{fclose(f1);}
	}

	for(i=0;i<256;++i){for(j=0;j<256;++j){ba2b[i][j][0][0]=1;}}

	f1=fopen(infn,"rb");
	fbyte=getc(f1);
	while((fbyte!=10)&&(fbyte!=13)){fbyte=getc(f1);}
	if(nli==0){while((fbyte==10)||(fbyte==13)){nl[nli]=fbyte;++nli;fbyte=getc(f1);}}
	fclose(f1);
	
	f1=fopen(infn,"rb");

	b1_=getc(f1);b1__=b1_;a=0;j=1;n=0;
	while(!feof(f1))
	{

		b2_=getc(f1);if(nl[a]==b2_){++a;}if(!(a<nli)){++j;a=0;}
		b3_=getc(f1);if(nl[a]==b3_){++a;}if(!(a<nli)){++j;a=0;}

		k=p_n(b1_,b3_,b2_);if(k==-1){printf("Error...\n");return(0);}
		ea[n]=e;eai=n;

		while(!feof(f1))
		{
			
			b2__=b2_;b2_=b3_;
			b3__=b3_;b3_=getc(f1);if(nl[a]==b3_){++a;}if(!(a<nli)){++j;a=0;}

			o=0;
			if(pa[0]=='1'){o|=1<<(0+(8*2));}
			if(pa[0]=='2'){o|=1<<(1+(8*2));}
			if(pa[0]=='4'){o|=1<<(0+(8*2));o|=1<<(1+(8*2));}
			if(pa[1]=='1'){o|=1<<(0+(7*2));}
			if(pa[1]=='2'){o|=1<<(1+(7*2));}
			if(pa[1]=='4'){o|=1<<(0+(7*2));o|=1<<(1+(7*2));}
			if(pa[2]=='1'){o|=1<<(0+(6*2));}
			if(pa[2]=='2'){o|=1<<(1+(6*2));}
			if(pa[2]=='4'){o|=1<<(0+(6*2));o|=1<<(1+(6*2));}
			if(pa[3]=='1'){o|=1<<(0+(5*2));}
			if(pa[3]=='2'){o|=1<<(1+(5*2));}
			if(pa[3]=='4'){o|=1<<(0+(5*2));o|=1<<(1+(5*2));}
			if(pa[4]=='1'){o|=1<<(0+(4*2));}
			if(pa[4]=='2'){o|=1<<(1+(4*2));}
			if(pa[4]=='4'){o|=1<<(0+(4*2));o|=1<<(1+(4*2));}
			if(pa[5]=='1'){o|=1<<(0+(3*2));}
			if(pa[5]=='2'){o|=1<<(1+(3*2));}
			if(pa[5]=='4'){o|=1<<(0+(3*2));o|=1<<(1+(3*2));}
			if(pa[6]=='1'){o|=1<<(0+(2*2));}
			if(pa[6]=='2'){o|=1<<(1+(2*2));}
			if(pa[6]=='4'){o|=1<<(0+(2*2));o|=1<<(1+(2*2));}
			if(pa[7]=='1'){o|=1<<(0+(1*2));}
			if(pa[7]=='2'){o|=1<<(1+(1*2));}
			if(pa[7]=='4'){o|=1<<(0+(1*2));o|=1<<(1+(1*2));}
			if(pa[8]=='1'){o|=1<<(0+(0*2));}
			if(pa[8]=='2'){o|=1<<(1+(0*2));}
			if(pa[8]=='4'){o|=1<<(0+(0*2));o|=1<<(1+(0*2));}

			++n;l=p_n(b1_,b3_,b2_);if(l==-1){printf("Error...\n");return(0);}
			ea[n]=e;eai=n;
			
			if(k!=l)
			{
				--n;
				b1_=b3_;

				sai=0;sa[sai]=b3__;++sai;
				r=b2__;for(i=n;i>=0;--i){r=p_r(b1__,r,k,o,i);}
				sa[sai]=b1__;++sai;for(i=sai-1;i>=0;--i){printf("%c",sa[i]);}
				printf("\t%d\t%d\n",n,j);

				if(ba2b[(b1__&0xff)][(b2__&0xff)][0][0]==1)
				{
					ba2b[(b1__&0xff)][(b2__&0xff)][ba2b[(b1__&0xff)][(b2__&0xff)][0][0]][0]=
					ba2b[(b1__&0xff)][(b2__&0xff)][0][0];
					ba2b[(b1__&0xff)][(b2__&0xff)][ba2b[(b1__&0xff)][(b2__&0xff)][0][0]][1]=k;
					ba2b[(b1__&0xff)][(b2__&0xff)][ba2b[(b1__&0xff)][(b2__&0xff)][0][0]][2]=n;
					ba2b[(b1__&0xff)][(b2__&0xff)][ba2b[(b1__&0xff)][(b2__&0xff)][0][0]][3]=o;
					++ba2b[(b1__&0xff)][(b2__&0xff)][0][0];

				}else{
					for(i=1;i<ba2b[(b1__&0xff)][(b2__&0xff)][0][0];++i)
					{
						if
						(
							(ba2b[(b1__&0xff)][(b2__&0xff)][i][1]==k)
							&&
							(ba2b[(b1__&0xff)][(b2__&0xff)][i][2]==n)
							&&
							(ba2b[(b1__&0xff)][(b2__&0xff)][i][3]==o)
						)
						{break;}
					}
					if(i==ba2b[(b1__&0xff)][(b2__&0xff)][0][0])
					{
						ba2b[(b1__&0xff)][(b2__&0xff)][ba2b[(b1__&0xff)][(b2__&0xff)][0][0]][0]=
						ba2b[(b1__&0xff)][(b2__&0xff)][0][0];
						ba2b[(b1__&0xff)][(b2__&0xff)][ba2b[(b1__&0xff)][(b2__&0xff)][0][0]][1]=k;
						ba2b[(b1__&0xff)][(b2__&0xff)][ba2b[(b1__&0xff)][(b2__&0xff)][0][0]][2]=n;
						ba2b[(b1__&0xff)][(b2__&0xff)][ba2b[(b1__&0xff)][(b2__&0xff)][0][0]][3]=o;
						++ba2b[(b1__&0xff)][(b2__&0xff)][0][0];
					}
				}

				b1__=b1_;n=0;break;

			}
		}
	}
	fclose(f1);

	for(a=0;a<256;++a)
	{
		for(b=0;b<256;++b)
		{
			if(ba2b[a][b][0][0]>1)
			{
				for(i=1;i<ba2b[a][b][0][0];++i)
				{

					printf("%c\t",a);
					printf("%d\t",a);
					if(((ba2b[a][b][i][3]>>16)&0x3)==1){printf("1");}
					if(((ba2b[a][b][i][3]>>16)&0x3)==2){printf("2");}
					if(((ba2b[a][b][i][3]>>16)&0x3)==3){printf("4");}
					if(((ba2b[a][b][i][3]>>14)&0x3)==1){printf("1");}
					if(((ba2b[a][b][i][3]>>14)&0x3)==2){printf("2");}
					if(((ba2b[a][b][i][3]>>14)&0x3)==3){printf("4");}
					if(((ba2b[a][b][i][3]>>12)&0x3)==1){printf("1");}
					if(((ba2b[a][b][i][3]>>12)&0x3)==2){printf("2");}
					if(((ba2b[a][b][i][3]>>12)&0x3)==3){printf("4");}
					if(((ba2b[a][b][i][3]>>10)&0x3)==1){printf("1");}
					if(((ba2b[a][b][i][3]>>10)&0x3)==2){printf("2");}
					if(((ba2b[a][b][i][3]>>10)&0x3)==3){printf("4");}
					if(((ba2b[a][b][i][3]>>8)&0x3)==1){printf("1");}
					if(((ba2b[a][b][i][3]>>8)&0x3)==2){printf("2");}
					if(((ba2b[a][b][i][3]>>8)&0x3)==3){printf("4");}
					if(((ba2b[a][b][i][3]>>6)&0x3)==1){printf("1");}
					if(((ba2b[a][b][i][3]>>6)&0x3)==2){printf("2");}
					if(((ba2b[a][b][i][3]>>6)&0x3)==3){printf("4");}
					if(((ba2b[a][b][i][3]>>4)&0x3)==1){printf("1");}
					if(((ba2b[a][b][i][3]>>4)&0x3)==2){printf("2");}
					if(((ba2b[a][b][i][3]>>4)&0x3)==3){printf("4");}
					if(((ba2b[a][b][i][3]>>2)&0x3)==1){printf("1");}
					if(((ba2b[a][b][i][3]>>2)&0x3)==2){printf("2");}
					if(((ba2b[a][b][i][3]>>2)&0x3)==3){printf("4");}
					if(((ba2b[a][b][i][3]>>0)&0x3)==1){printf("1");}
					if(((ba2b[a][b][i][3]>>0)&0x3)==2){printf("2");}
					if(((ba2b[a][b][i][3]>>0)&0x3)==3){printf("4");}
					printf("\t%d\t%d\t%c\n",ba2b[a][b][i][1],ba2b[a][b][i][2],b);
					//printf("\t%d\t%d\t%d\n",ba2b[a][b][i][1],ba2b[a][b][i][2],b);

					if(ba2b[a][b][i][2]==0){++unmc;}else{++mc;}
				}
			}
		}
	}

	printf("\t%e\n\n",(100*((double)unmc/(double)mc)));

	return(0);
}