home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 15
/
CD_ASCQ_15_070894.iso
/
vrac
/
tpchal_1.zip
/
TS.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-06-09
|
4KB
|
109 lines
/* Generate a program to find the solution to the 9-digit problem
** at compile time:
** Find a 9 digit decimal number, d1 d2 ... d9, using each digit
** 1 through 9 once, so that the i-digit number defined by
** d1 through di is divisible by i.
**
** This problem has been solved many times in different ways.
** This solution, inspired by Auke Reitsma, generates the solution
** at compile time (compile time of the generated program).
**
** This program generates the following files:
** find9.c ck0.h ck1.h ck2.h ck3.h ck4.h ck5.h ck6.h ck7.h ck8.h ck9.h
** Compiling find9.c will generate code to print every answer, via
** puts().
**
** Instructions:
** Compile and run this program.
** Compile and run find9.c.
**
** Note: The generated program requires 10 levels of nested includes,
** which exceeds the ANSI minimum support of 8.
** Most environments handle this without problems.
**
** This seems to be a good stress test. Note the patch below
** to explicitly evaluate the expression as long for Borland.
** Zortech's compiler fails to evaluate the #s preprocessor
** operator properly. Microsofts QC 2.51 bombs, as does
** Mix Power C. Turbo C 2.01 runs out of memory.
**
** Written by Thad Smith 6/03/94 and donated to the public domain.
*/
#include <stdio.h>
#include <stdlib.h>
FILE *fx;
/* Generate output "((...(D1*10)+D2)*10...)" */
void expr(int d) {
#ifdef __TURBOC__ /* BC++ 3.1 doesn't do preprocessor evaluation
** with long precision, as required [6.8.1] */
if (d==1) fprintf (fx, "D1*1L");
#else /* ANSI/ISO conforming */
if (d==1) fprintf (fx, "D1");
#endif
else {
fprintf (fx, "(");
expr (d-1);
fprintf (fx, "*10+D%d)", d);
}
}
main() {
int i,d;
char fn[5]; /* file name */
/* Write the main program */
fx = fopen ("find9.c", "w");
fprintf (fx, "#include <stdio.h>\n");
fprintf (fx, "#define str(s) #s\n");
fprintf (fx, "#define xstr(s) str(s)\n");
fprintf (fx, "main() {\n");
fprintf (fx, "#include \"ck0.h\"\n");
fprintf (fx, "return 0;\n");
fprintf (fx, "}\n");
fclose (fx);
/* Write the first 8 include files.
** Each one tries all possible digits for the
** associated position, calling the next level when
** a fit is found.
*/
for (d=0; d <= 8; d++) {
sprintf(fn, "ck%d.h", d);
fx = fopen(fn, "w");
if (!fx) {
printf ("error opening file %s\n", fn);
exit(1);
}
if (d > 0) {
fprintf (fx, "#undef V%d\n",d);
fprintf (fx, "#define V%d ",d);
expr(d);
fprintf (fx, "\n");
}
for (i=1; i<=9; i++) {
if (d > 0) {
fprintf (fx, "#if !defined U%d && (V%d*10+%d) %% %d == 0\n",
i, d, i, d+1);
}
fprintf (fx, " #define D%d %d\n", d+1, i);
fprintf (fx, " #define U%d\n", i);
fprintf (fx, " #include \"ck%d.h\"\n", d+1);
fprintf (fx, " #undef D%d\n", d+1);
fprintf (fx, " #undef U%d\n", i);
if (d>0) fprintf (fx, "#endif\n");
}
fclose (fx);
}
/* ck9 prints the answer */
fx = fopen ("ck9.h", "w");
fprintf (fx, "puts(xstr(D1) xstr(D2) xstr(D3) xstr(D4) \n"
"\txstr(D5) xstr(D6) xstr(D7) xstr(D8) xstr(D9));\n");
fclose (fx);
return 0;
}