/* matrix.c  by Scott McClelland 07/92, 01/07/94
copyright (c) 1994 WordPro Information Systems
------------------------------------------------------------
Compiled with Turbo C using tiny memory model, and linked
to a .COM file for optimum speed.
Translation from BASIC to C 12/93
------------------------------------------------------------ */
/* Designed to calculate a linear algebra problem while the
computer is idle.  Program uses nine nested for loops to
check values of 200^9 posible combinations, and finds the
determinant of a 3 X 3 matrix for each combination.  Intermediate
values are stored in a log file after a time delay (based on loop
iterations), or keystroke.
-------------------------------------------------------------
The program attempts to find a matrix with a determinant equal
to one, and the matrix formed by squaring all terms also equal
to one.
-------------------------------------------------------------*/

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

int a, b, c, d, e, f, g, h, i,        /* a - i are counters */
x, y,                     /* x, y are answers  */
min, max, midval,         /* range to chk */
found = 0;                /* flag whether soln found or not */
int a2,b2,c2,d2,e2,f2,g2,h2,i2;       /* terms squared */
int mina, minb, minc, mind, mine, minf, ming, minh, mini; /* min values */
int maxa, maxb, maxc, maxd, maxe, maxf, maxg, maxh, maxi; /* max values */
int col, row;                                   /* screen positions */

static char *help[] =
{
"\t\t- - - - -  MATRIX.C - - - - - ",
" ",
"Program runs a screen saver while testing a mathematical problem in",
"linear algebra.  The program attempts to find a 3 x 3 matrix with",
"a determinant equal to one, and when all terms are squared, the",
"determinant is also equal to one.  Zeros are not allowed as terms. ",
" ",
""        /* Null char terminates string */
};

/* function prototypes */
void show_help();
void pause(void);
void init( void);
void initmax(void);
void showcount(void);
savelog(void);
void quitprog(void);

main()
{
int cont = 0;
clrscr();
/* initialize vars & read values */
readlog( ); /* sets new starting values from file */
while(cont == 0) /* loop forever */
{
initmax();
midval = ((min < 0 ) ? max+min : max-min ); /* middle value assuming max > 0 */
for( a = mina; a <= maxa; ++a ){
if( a == 0 ) ++a;               /* zeros not allowed in calc (skip them) */
if ( a == mina + 1)         /* first time through loop */
if ( minb > min) minb = min;      /* Resets min value when different */
for( b = minb; b <= maxb; ++b ){
if ( b == 0 ) ++b;
if ( b == minb + 1)
if ( minc > min) minc = min;
for( c = minc; c <= maxc; ++c ){
if ( c == 0 ) ++c;
if ( c == minc + 1)
if ( mind > min) mind = min;
for( d = mind; d <= maxd; ++d ){
if ( d == 0 ){
++d;
/* chk for 'time' elapse to write to file at d, e, f or g  */
savelog();
}
if ( d == mind + 1)
if ( mine > min) mine = min;
for( e = mine; e <= maxe; ++e ){
if (e == 0) ++e;
if ( e == mine + 1)
if ( minf > min) minf = min;
for( f = minf; f <= maxf; ++f ){
if ( f == 0 )
++f;
if ( f == minf + 1)
if ( ming > min) ming = min;
for( g = ming; g <= maxg; ++g ){
if ( g == 0 ){
++g;
/* display current values, and show that any key will terminate program */
/* moved to main to avoid the overhead of a fuction call */
/* set col, row to some random value */
randomize();
col = random(47);  /* use fibronichi method for more speed (write funct later) */
row = random(22) + 1 ;
clrscr();
gotoxy( col, row);                 /* show value of counters */
if (found == 0)
printf("Press any key to restore screen...\n" );
else
printf("Found %d Soln(s)! Press any key...\n", found);
gotoxy( col, row+1);
printf("%d %d %d %d %d %d ... ",a,b,c,d,e,f);
} /* if g == 0*/

/* chk for keystroke to write to file & quit at g or h */
if (kbhit())  /* allow user to exit by pressing any key */
quitprog();
if ( g == ming + 1)
if ( minh > min) minh = min;
for( h = minh; h <= maxh; ++h ){
if ( h == 0 ) ++h;
if ( h == minh + 1)
if ( mini > min) mini = min;
for( i = mini; i <= maxi; ++i ) {
if ( i == 0 ) ++i;
/* main calculation */
x = a * ((e * i)-(f * h)) - b *
((d * i)-(g * f)) + c *((d * h)-(g * e));
if (x == 1){  /* x is first determinant */
/* calcmatrix2(); function used to determine placement in loop structure */
/* calculate in main to save time by avoiding a function call */
/* square the terms, find 2nd determinant */
a2 = a * a; b2 = b * b; c2 = c * c;
d2 = d * d; e2 = e * e; f2 = f * f;
g2 = g * g; h2 = h * h; i2 = i * i;
y = a2 * ((e2 * i2)-(f2 * h2)) - b2 *
((d2 * i2)-(g2 * f2)) + c2 * ((d2 * h2)-(g2 * e2));
if (y == 1)  /* check 2nd determ equal to one */
} /* if x == 1 */
}       /* end for i */
}         /* end for h */
}           /* end for g */
}             /* end for f */
}               /* end for e */
}                 /* end for d */
}                   /* end for c */
}                     /* end for b */
}                       /* end for a */

/* resets min & max values if numbers reach the end of test range */
min = -999; max = 999;
found = 0;
init(); /* reset loop counter values */
} /* end while */

return(0);
} /* main */
/* ---------------------------------------------------------------------- */

void show_help()  /* explain program as processing begins */
{    /* *help defined above as static char pointer */
int index;
clrscr();
for ( index=0; *help[index]; index++ ) puts( help[index] );
}

void pause(void)
{
char ch;
printf("Press any key to continue...");
ch = getch();
printf("%c", ch);
}

void init( void) /* sets values if loop reaches end */
{
mina = minb = minc = mind = mine = minf = ming = minh = mini = min;
maxa = maxb = maxc = maxd = maxe = maxf = maxg = maxh = maxi = max;
}

void initmax(void) /* sets max values, although max could be used for
all 9 vars, rather than using nine different vars. */
{
maxa = maxb = maxc = maxd = maxe = maxf = maxg = maxh = maxi = max;
}

/* ---------------------------------------------------------------------- */
{

FILE *fp, *fopen();
if ((fp = fopen("matrix.log", "r" )) == NULL) {
printf("Can't open log file\nChange to directory containing MATRIX.LOG,\nor create new log file with SETUP\n");
pause();
exit(1);
}
/* read loop counter values from log file */
fscanf( fp, "%d %d %d %d %d %d %d %d %d %d %d",
&mina,&minb,&minc,&mind,&mine,&minf,&ming,&minh,&mini,&min,&max );
fclose(fp);
show_help(); /* explain program while calculating */
printf("Calculating...\n\nStarting with matrix:\n\n");
printf("\t³ %5d %5d %5d ³\n\t³ %5d %5d %5d ³\n\t³ %5d %5d %5d ³\n\nin the range of %d to %d\n",
mina,minb,minc,mind,mine,minf,ming,minh,mini,min,max);
printf("\nPress any key to restore screen at any time during execution of program..." );
}

void showcount(void) /* move to main to save funct call time */
{
int col, row;
/* set col, row to some random value */
randomize();
col = random(47);  /* use fibronichi method for more speed (write funct later) */
row = random(22) + 1 ;
clrscr();
/* value of counters may be one more then max.  If so, decrement counter. */
/* (not needed if function is eliminated and operations are moved to main) */
if (a > maxa) a--; if (b > maxb) b--; if (c > maxc) c--; if (d > maxd) d--;
if (e > maxe) e--; if (f > maxf) f--; if (g > maxg) g--; if (h > maxh) h--;
if (i > maxi) i--; /* not needed in main */

gotoxy( col, row);                 /* show value of counters */
if (found == 0)
printf("Press any key to restore screen...\n" );
else
printf("Found %d Soln(s)! Press any key...\n", found);
gotoxy( col, row+1);
printf("%d %d %d %d %d %d %d %d %d\n",a,b,c,d,e,f,max, max, max);
}

savelog(void) /* saves current values of a through i */
{
FILE *fp, *fopen();
if ((fp = fopen("matrix.log", "w" )) == NULL) {
printf("Can't open log file\n");
pause();
return(1);
}
/* value of counters may be one more then max.  If so, decrement counter */
if (a > maxa) a--; if (b > maxb) b--; if (c > maxc) c--; if (d > maxd) d--;
if (e > maxe) e--; if (f > maxf) f--; if (g > maxg) g--; if (h > maxh) h--;
if (i > maxi) i--;

fprintf( fp, "%d %d %d %d %d %d %d %d %d %d %d ",a,b,c,d,e,f,g,h,i,min,max );
fclose(fp);

/*  gotoxy(1,3);
printf("\nSaving log file...\n%d %d %d %d %d %d %d %d %d %d %d\n",
a,b,c,d,e,f,g,h,i,min,max );  */       /* beta */
return(0);
}

void quitprog(void)
{
savelog();
/* reset screen - white foreground, black background */
textattr( BLACK * 16 + LIGHTGRAY );
clrscr();
gotoxy(20,3);
printf("\nSaving log file...\n%d %d %d %d %d %d %d %d %d range: %d to %d\n",
a,b,c,d,e,f,g,h,i,min,max );
exit(0);
}

{
FILE *fp, *fopen();
if ((fp = fopen("answer.log", "a" )) == NULL) {
pause();
return(1);
}
fprintf( fp, "%d %d %d %d %d %d %d %d %d %d %d\n",a,b,c,d,e,f,g,h,i,min,max );
fclose(fp);

found++;
printf("\nfound %d answer(s): \n%d %d %d\n%d %d %d\n%d %d %d\n",
"in the range of %d to %d\n",found,a,b,c,d,e,f,g,h,i,min,max );
return(0);
}

/* moved to main for faster processing */
calcmatrix2(void) /* called if first determ = 1 */
{
/* square the terms, find 2nd determinant */
a2 = a * a; b2 = b * b; c2 = c * c; d2 = d * d; e2 = e * e;
f2 = f * f; g2 = g * g; h2 = h * h; i2 = i * i;
y = a2 * ((e2 * i2)-(f2 * h2)) - b2 * ((d2 * i2)-(g2 * f2)) + c2 * ((d2 * h2)-(g2 * e2));
if (y == 1)  /* check if equal to one */