//	This source and sum of bit parity distances method apply to GNU General Public License. 
//			Copyright (C) 2013 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.

//  		Sum of bit parity distances
//		written by Dzinleski Jasenko August-September 2013

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

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

int	b8o,b8e;

int	b1,b2,b3;

int	d1,d2,d3;
int	d1_,d2_,d3_;
int	d3__;

int	i,j,k,l;
int	p;

int	s1,s21,s22,s23;

int	a1[9];int a1i;
int	s;
int	t;
int	a=0,e=0;

int	ra[9][5];
char	da[100][10];int dai=0;
int	df=0;


for(i=0;i<9;++i){for(j=0;j<5;++j){ra[i][j]=0;}}

b8o=0;
b8o|=1<<0;
b8o|=1<<2;
b8o|=1<<4;
b8o|=1<<6;

b8e=0;
b8e|=1<<1;
b8e|=1<<3;
b8e|=1<<5;
b8e|=1<<7;

//	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;
	b1=b1_<<1;
	b2=b2_<<1;
	b3=b3_<<1;

	d1=((((b1&b8e)>>1)^(b2&b8o))|((b1&b8e)^((b2&b8o)<<1)));	
	d2=((((b1&b8e)>>1)^(b3&b8o))|((b1&b8e)^((b3&b8o)<<1)));

	d1_=((((b2&b8e)>>1)^(b1&b8o))|((b2&b8e)^((b1&b8o)<<1)));	
	d2_=((((b2&b8e)>>1)^(b3&b8o))|((b2&b8e)^((b3&b8o)<<1)));
	d3__=((((d1&b8e)>>1)^(d2_&b8o))|((d1&b8e)^((d2_&b8o)<<1)));

	if(df==1){printf("%d\t%d\t%d\n",i,s,a);}

	if((((t-b3_)>=-4)&&((t-b3_)<=4)))
	{

		++ra[0][a1[0]];
		++ra[1][a1[1]];
		++ra[2][a1[2]];
		++ra[3][a1[3]];
		++ra[4][a1[4]];
		++ra[5][a1[5]];
		++ra[6][a1[6]];
		++ra[7][a1[7]];
		++ra[8][a1[8]];

		if(dai==0)
		{
			da[dai][0]=a1[0]+48;
			da[dai][1]=a1[1]+48;
			da[dai][2]=a1[2]+48;
			da[dai][3]=a1[3]+48;
			da[dai][4]=a1[4]+48;
			da[dai][5]=a1[5]+48;
			da[dai][6]=a1[6]+48;
			da[dai][7]=a1[7]+48;
			da[dai][8]=a1[8]+48;
			++dai;
		}else{
			for(p=0;p<dai;++p)
			{
				if
				(
				da[p][0]==a1[0]+48&&
				da[p][1]==a1[1]+48&&
				da[p][2]==a1[2]+48&&
				da[p][3]==a1[3]+48&&
				da[p][4]==a1[4]+48&&
				da[p][5]==a1[5]+48&&
				da[p][6]==a1[6]+48&&
				da[p][7]==a1[7]+48&&
				da[p][8]==a1[8]+48
				){break;}
			}
			if(p==dai)
			{
				da[dai][0]=a1[0]+48;
				da[dai][1]=a1[1]+48;
				da[dai][2]=a1[2]+48;
				da[dai][3]=a1[3]+48;
				da[dai][4]=a1[4]+48;
				da[dai][5]=a1[5]+48;
				da[dai][6]=a1[6]+48;
				da[dai][7]=a1[7]+48;
				da[dai][8]=a1[8]+48;
				++dai;
			}
		}

		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;
	b1=b1_<<1;
	b2=b2_<<1;
	b3=b3_<<1;

	d1=((((b1&b8e)>>1)^(b2&b8o))|((b1&b8e)^((b2&b8o)<<1)));	
	d2=((((b1&b8e)>>1)^(b3&b8o))|((b1&b8e)^((b3&b8o)<<1)));

	d1_=((((b2&b8e)>>1)^(b1&b8o))|((b2&b8e)^((b1&b8o)<<1)));	
	d2_=((((b2&b8e)>>1)^(b3&b8o))|((b2&b8e)^((b3&b8o)<<1)));
	d3__=((((d1&b8e)>>1)^(d2_&b8o))|((d1&b8e)^((d2_&b8o)<<1)));

	if(df==1){printf("%d\t%d\t%d\n",i,s,a);}

	if((((t-b3_)>=-4)&&((t-b3_)<=4)))
	{

		++ra[0][a1[0]];
		++ra[1][a1[1]];
		++ra[2][a1[2]];
		++ra[3][a1[3]];
		++ra[4][a1[4]];
		++ra[5][a1[5]];
		++ra[6][a1[6]];
		++ra[7][a1[7]];
		++ra[8][a1[8]];

		if(dai==0)
		{
			da[dai][0]=a1[0]+48;
			da[dai][1]=a1[1]+48;
			da[dai][2]=a1[2]+48;
			da[dai][3]=a1[3]+48;
			da[dai][4]=a1[4]+48;
			da[dai][5]=a1[5]+48;
			da[dai][6]=a1[6]+48;
			da[dai][7]=a1[7]+48;
			da[dai][8]=a1[8]+48;
			++dai;
		}else{
			for(p=0;p<dai;++p)
			{
				if
				(
				da[p][0]==a1[0]+48&&
				da[p][1]==a1[1]+48&&
				da[p][2]==a1[2]+48&&
				da[p][3]==a1[3]+48&&
				da[p][4]==a1[4]+48&&
				da[p][5]==a1[5]+48&&
				da[p][6]==a1[6]+48&&
				da[p][7]==a1[7]+48&&
				da[p][8]==a1[8]+48
				){break;}
			}
			if(p==dai)
			{
				da[dai][0]=a1[0]+48;
				da[dai][1]=a1[1]+48;
				da[dai][2]=a1[2]+48;
				da[dai][3]=a1[3]+48;
				da[dai][4]=a1[4]+48;
				da[dai][5]=a1[5]+48;
				da[dai][6]=a1[6]+48;
				da[dai][7]=a1[7]+48;
				da[dai][8]=a1[8]+48;
				++dai;
			}
		}

		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%c%c%c%c%c%c%c%c%c\n",da[p][0],da[p][1],da[p][2],da[p][3],da[p][4],da[p][5],da[p][6],da[p][7],da[p][8]);
printf("\n%d %d %e\n\n",e,a,100.00-100.00*((double)e/(double)a));
}

return(a);
}

int main()
{

int i,j,k;

for(i=1;i<256;++i){for(j=1;j<256;++j){for(k=1;k<256;++k){if(-1==p_(i,j,k)){printf("Error... %d\t%d\t%d\n",i,j,k);}}}}

return(0);

}