home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 15 / CD_ASCQ_15_070894.iso / vrac / tpchal_1.zip / TS.C < prev    next >
C/C++ Source or Header  |  1994-06-09  |  4KB  |  109 lines

  1. /* Generate a program to find the solution to the 9-digit problem
  2. ** at compile time:
  3. **   Find a 9 digit decimal number, d1 d2 ... d9, using each digit
  4. **   1 through 9 once, so that the i-digit number defined by
  5. **   d1 through di is divisible by i.
  6. **
  7. ** This problem has been solved many times in different ways.
  8. ** This solution, inspired by Auke Reitsma, generates the solution
  9. ** at compile time (compile time of the generated program).
  10. **
  11. ** This program generates the following files:
  12. ** find9.c ck0.h ck1.h ck2.h ck3.h ck4.h ck5.h ck6.h ck7.h ck8.h ck9.h
  13. ** Compiling find9.c will generate code to print every answer, via
  14. ** puts().
  15. **
  16. ** Instructions:
  17. **  Compile and run this program.
  18. **  Compile and run find9.c.
  19. **
  20. ** Note:  The generated program requires 10 levels of nested includes,
  21. **        which exceeds the ANSI minimum support of 8.
  22. **        Most environments handle this without problems.
  23. **
  24. ** This seems to be a good stress test.  Note the patch below
  25. ** to explicitly evaluate the expression as long for Borland.
  26. ** Zortech's compiler fails to evaluate the #s preprocessor
  27. ** operator properly.  Microsofts QC 2.51 bombs, as does
  28. ** Mix Power C.  Turbo C 2.01 runs out of memory.
  29. **
  30. ** Written by Thad Smith  6/03/94 and donated to the public domain.
  31. */
  32.  
  33. #include <stdio.h>
  34. #include <stdlib.h>
  35.  
  36. FILE *fx;
  37.  
  38. /* Generate output "((...(D1*10)+D2)*10...)" */
  39. void expr(int d) {
  40. #ifdef __TURBOC__   /* BC++ 3.1 doesn't do preprocessor evaluation
  41.                     ** with long precision, as required [6.8.1]    */
  42.     if (d==1) fprintf (fx, "D1*1L");
  43. #else               /* ANSI/ISO conforming */
  44.     if (d==1) fprintf (fx, "D1");
  45. #endif
  46.     else {
  47.         fprintf (fx, "(");
  48.         expr (d-1);
  49.         fprintf (fx, "*10+D%d)", d);
  50.     }
  51. }
  52.  
  53. main() {
  54.     int i,d;
  55.     char fn[5];     /* file name */
  56.  
  57.     /* Write the main program */
  58.     fx = fopen ("find9.c", "w");
  59.     fprintf (fx, "#include <stdio.h>\n");
  60.     fprintf (fx, "#define str(s) #s\n");
  61.     fprintf (fx, "#define xstr(s) str(s)\n");
  62.     fprintf (fx, "main() {\n");
  63.     fprintf (fx, "#include \"ck0.h\"\n");
  64.     fprintf (fx, "return 0;\n");
  65.     fprintf (fx, "}\n");
  66.     fclose (fx);
  67.  
  68.     /* Write the first 8 include files.
  69.     ** Each one tries all possible digits for the
  70.     ** associated position, calling the next level when
  71.     ** a fit is found.
  72.     */
  73.     for (d=0; d <= 8; d++) {
  74.         sprintf(fn, "ck%d.h", d);
  75.         fx = fopen(fn, "w");
  76.         if (!fx) {
  77.             printf ("error opening file %s\n", fn);
  78.             exit(1);
  79.         }
  80.  
  81.         if (d > 0) {
  82.             fprintf (fx, "#undef V%d\n",d);
  83.             fprintf (fx, "#define V%d ",d);
  84.             expr(d);
  85.             fprintf (fx, "\n");
  86.         }
  87.         for (i=1; i<=9; i++) {
  88.             if (d > 0) {
  89.                 fprintf (fx, "#if !defined U%d && (V%d*10+%d) %% %d == 0\n",
  90.                     i, d, i, d+1);
  91.             }
  92.             fprintf (fx, "  #define D%d %d\n", d+1, i);
  93.             fprintf (fx, "  #define U%d\n", i);
  94.             fprintf (fx, "  #include \"ck%d.h\"\n", d+1);
  95.             fprintf (fx, "  #undef  D%d\n", d+1);
  96.             fprintf (fx, "  #undef  U%d\n", i);
  97.             if (d>0)    fprintf (fx, "#endif\n");
  98.         }
  99.         fclose (fx);
  100.     }
  101.     /* ck9 prints the answer */
  102.     fx = fopen ("ck9.h", "w");
  103.     fprintf (fx, "puts(xstr(D1) xstr(D2) xstr(D3) xstr(D4) \n"
  104.            "\txstr(D5) xstr(D6) xstr(D7) xstr(D8) xstr(D9));\n");
  105.     fclose (fx);
  106.  
  107.     return 0;
  108. }
  109.