// 1/15/2006 DCC CDvars.c creates XOR-based mult table template, then fills in +/-'s for extension beyond upper left quaternion corner, according to
// value of formmask; formmask codes as an int 0-511 the C-D form being tested:
// (a,b)(c,d) = (ac - [bd][ *][db][ *], [ad][ *][da][ *] + [bc][ *][cb][ *])
// bits in formmask:
//	0: bd or db
//	1: b*
//	2: d*
//	3: ad or da
//	4: a*
//	5: d*
//	6: bc or cb
//	7: b*
//	8: c*
// 
// Since (AB)* = B*A* is violated by 1 && 2 above, and by 4 && 8, and by 5 <> 7, and 3 && 6, filters suppress calce for such
// output is html  format of octonion multiplication tables, labelled with C-D multiplication formula producing it
#include 

int main() {
	int i, j, k, l, formmask, bd, ad, bc;
	FILE *fp;
	int triads[7][3] = {{1,2,3},{1,4,5},{1,6,7},{2,4,6},{2,5,7},{3,4,7},{3,5,6}}; // XOR rep, as per canonical mapping for C-D
	int M0[8][8], S[8][8];
	char Sc[8][8], odd, even, CDform[50];
	char filnam[50];
	printf("Output results to: ");
	scanf("%s", filnam);
	fp = fopen(filnam, "w");
	fclose(fp); // reinit output file
	M0[0][0] = 0;
	for(i=0; i<8; i++) for(j=0; j<8; j++) {
		Sc[i][j] = ' ';
		S[i][j] = 1;
	}
	S[2][1] = S[3][2] = S[1][3] = -1;
	for(i=1; i<8; i++) 
	{
		M0[0][i] = M0[i][0] = i;
		M0[i][i] = 0;
		Sc[i][i] = '-';
		S[i][i] = -1;
	}
	for(i=0; i<7; i++)
	{
		for(j=0; j<3; j++)
		{
			M0[triads[i][j]][triads[i][(j+1)%3]] = triads[i][(j+2)%3];
			M0[triads[i][(j+1)%3]][triads[i][j]] = triads[i][(j+2)%3];
		}
	}
	for(formmask=0,l=1; formmask<512; formmask++)
	{
		if((formmask & 2) == (formmask & 4)/2) continue;
		if((formmask & 8) == (formmask & 64)/8) continue;
		if((formmask & 16) == (formmask & 256)/16) continue;
		if((formmask & 32) != (formmask & 128)/4) continue;
// temp for just (.., d* + b*) ones
//if(!(formmask & 160)) continue;
		bd = formmask & 7;
		ad = (formmask & 7*8)/8;
		bc = (formmask & 7*8*8)/64;
	// now set up signs in S[][] for current C-D formula
		//center cross, 9:00, 12:00, 3:00, 6:00
		i=1;
		if(formmask & 1<<8) i = -1;
		for(j=1;j<4;j++) S[4][j] = i;
		i=1;
		if(formmask & 1<<4) i = -1;
		for(j=1;j<4;j++) S[j][4] = i;
		i=-1;
		if(formmask & 1<<2) i = 1;
		for(j=5;j<8;j++) S[4][j] = i;
		i=-1;
		if(formmask & 1<<1) i = 1;
		for(j=5;j<8;j++) S[j][4] = i;
		// lower left square (but for its diagonal)
		i=1;
		if(formmask & 1<<6) i *= -1;
		if(formmask & 1<<7) i *= -1;
		if(formmask & 1<<8) i *= -1;
		for(j=1; j<4; j++)
			for(k=1;k<4;k++) 
				if(j!=k) S[j+4][k] = i*S[j][k]; 
		// upper right square (but for its diagonal)
		i=1;
		if(formmask & 1<<3) i *= -1;
		if(formmask & 1<<4) i *= -1;
		if(formmask & 1<<5) i *= -1;
		for(j=1; j<4; j++)
			for(k=1;k<4;k++) 
				if(j!=k) S[j][k+4] = i*S[j][k]; 

		// lower right square (but for diagonal)
		i=-1;
		if(formmask & 1<<0) i *= -1;
		if(formmask & 1<<1) i *= -1;
		if(formmask & 1<<2) i *= -1;
		for(j=1; j<4; j++)
			for(k=1;k<4;k++) 
				if(j!=k) S[j+4][k+4] = i*S[j][k]; 

		// lower left's diagonal
		i=-1;
		if(formmask & 1<<7) i *= -1;
		if(formmask & 1<<8) i *= -1;
		for(j=1; j<4; j++) S[j+4][j] = i;
		// upper right's diagonal
		i=-1;
		if(formmask & 1<<4) i *= -1;
		if(formmask & 1<<5) i *= -1;
		for(j=1; j<4; j++) S[j][j+4] = i;

		for(i=1;i<8;i++) for(j=1; j<8; j++) Sc[i][j] = ' ';
		for(i=1;i<8;i++) for(j=1; j<8; j++) if(S[i][j] == -1) Sc[i][j] = '-';
	// now print out the full "hopefully octonion" multiplication table for current C-D formula
		fp = fopen(filnam,"a");
		fprintf(fp,"<table><tr><td><table border=1>\n");
		fprintf(fp,"<tr><th></th>");
		for(j=0; j<8; j++)
			fprintf(fp,"<th> e<sub>%d</sub> </th>", M0[0][j]);
		fprintf(fp,"</tr>\n");
		for(i=0; i<8; i++)
		{
			fprintf(fp,"<tr><td> <b>e<sub>%d</sub></b> </td>", M0[i][0]);
			for(j=0; j<8; j++)
				fprintf(fp,"<td> %ce<sub>%d</sub> </td>", Sc[i][j], M0[i][j]);
			fprintf(fp,"</tr>\n");
		}
		fprintf(fp,"</table></td><td valign=top>");
	// print out the current C-D multiplication formula:
		fprintf(fp,"<h3>%d %x: ", l++, formmask);
		fprintf(fp,"(ac - ");
		if(bd==0) fprintf(fp,"bd, ");
		if(bd==1) fprintf(fp,"db, ");
		if(bd==2) fprintf(fp,"b*d, ");
		if(bd==3) fprintf(fp,"db*, ");
		if(bd==4) fprintf(fp,"bd*, ");
		if(bd==5) fprintf(fp,"d*b, ");
		if(bd==6) 
			fprintf(fp,"b*d*, ");
		if(bd==7) 
			fprintf(fp,"d*b*, ");
		if(ad==0) fprintf(fp,"ad + ");
		if(ad==1) fprintf(fp,"da + ");
		if(ad==2) fprintf(fp,"a*d + ");
		if(ad==3) fprintf(fp,"da* + ");
		if(ad==4) fprintf(fp,"ad* + ");
		if(ad==5) fprintf(fp,"d*a + ");
		if(ad==6) fprintf(fp,"a*d* + ");
		if(ad==7) fprintf(fp,"d*a* + ");
		if(bc==0) fprintf(fp,"bc)");
		if(bc==1) fprintf(fp,"cb)");
		if(bc==2) fprintf(fp,"b*c)");
		if(bc==3) fprintf(fp,"cb*)");
		if(bc==4) fprintf(fp,"bc*)");
		if(bc==5) fprintf(fp,"c*b)");
		if(bc==6) fprintf(fp,"b*c*)");
		if(bc==7) fprintf(fp,"c*b*)");
		fprintf(fp,"</h3>\n <b>Comments:</b><br><br></td></tr></table>\n");
		fclose(fp);
	}
}