Advertisement
Guest User

Untitled

a guest
Feb 11th, 2016
49
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.74 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. #define ORDER 4
  5. #define MSUM ((ORDER * (ORDER * ORDER + 1)) >> 1)
  6.  
  7. typedef unsigned char byte;
  8. typedef enum boolean { false = 0, true } boolean;
  9.  
  10. static byte board[ORDER][ORDER];
  11. static byte used[ORDER * ORDER + 1];
  12.  
  13. #ifdef SPINNER
  14. static char spinner[] = "|/-\\";
  15. static byte spin;
  16. #endif
  17.  
  18. /*
  19.  * a new number n is acceptable if it's not already used
  20.  * and if the sum doesn't overflow the magic sum MSUM
  21.  */
  22. static boolean acceptable_n(byte row, byte col, byte n)
  23. {
  24.     byte        i;
  25.     unsigned int sum1, sum2, d1sum, d2sum;
  26.  
  27.     if (used[n])
  28.         return false;
  29.  
  30.     sum1 = sum2 = n;
  31.     for (i = 0; i < ORDER; ++i) {
  32.         sum1 += board[row][i];
  33.         sum2 += board[i][col];
  34.     }
  35.     if (col == ORDER - 1) {
  36.         if (sum1 != MSUM || sum2 > MSUM)
  37.             return false;
  38.     } else {
  39.         if (sum1 > MSUM || sum2 > MSUM)
  40.             return false;
  41.     }
  42.  
  43.     d1sum = d2sum = 0;
  44.     for (i = 0; i < ORDER; ++i) {
  45.         d1sum += board[i][i];
  46.         d2sum += board[ORDER - 1 - i][i];
  47.     }
  48.  
  49.     if (d1sum > MSUM || d2sum > MSUM)
  50.         return false;
  51.  
  52.     return true;
  53. }
  54.  
  55. /*
  56.  * a solution is one of which all the sums are exactly
  57.  * the magic sum MSUM
  58.  */
  59. static boolean all_ok(void)
  60. {
  61.     byte        row, col, i;
  62.     unsigned int sum, d1sum, d2sum;
  63.  
  64.     for (row = 0; row < ORDER; ++row) {
  65.         sum = 0;
  66.         for (col = 0; col < ORDER; ++col)
  67.             sum += board[row][col];
  68.         if (sum != MSUM)
  69.             return false;
  70.     }
  71.  
  72.     for (col = 0; col < ORDER; ++col) {
  73.         sum = 0;
  74.         for (row = 0; row < ORDER; ++row)
  75.             sum += board[row][col];
  76.         if (sum != MSUM)
  77.             return false;
  78.     }
  79.  
  80.     d1sum = d2sum = 0;
  81.     for (i = 0; i < ORDER; ++i) {
  82.         d1sum += board[i][i];
  83.         d2sum += board[ORDER - 1 - i][i];
  84.     }
  85.  
  86.     if (d1sum != MSUM || d2sum != MSUM)
  87.         return false;
  88.     return true;
  89. }
  90.  
  91. static void print_board(void)
  92. {
  93.     byte        row, col;
  94.  
  95.     for (row = 0; row < ORDER; ++row) {
  96.         for (col = 0; col < ORDER; ++col) {
  97.             printf("%4d", board[row][col]);
  98.         }
  99.         putchar('\n');
  100.     }
  101. }
  102.  
  103. static boolean solve(byte row, byte col)
  104. {
  105.     byte        n;
  106.  
  107.     /* we found a solution */
  108.     if (row == ORDER && all_ok())
  109.         return true;
  110.  
  111.     /*
  112.      * no solution yet, check for an n which fits
  113.      * this position
  114.      */
  115.     for (n = 1; n < ORDER * ORDER + 1; ++n) {
  116.         /* only acceptable n's are tried for speed */
  117.         if (acceptable_n(row, col, n)) {
  118.             board[row][col] = n;
  119.             used[n] = true;
  120.             if (col == ORDER - 1) {
  121.                 if (solve(row + 1, 0))
  122.                     return true;
  123.             } else {
  124.                 if (solve(row, col + 1))
  125.                     return true;
  126.             }
  127.             /* backtrack: try this one again if above fails */
  128.             board[row][col] = 0;
  129.             used[n] = false;
  130. #ifdef SPINNER
  131.             printf("%c\r", spinner[spin++]);
  132.             if (spin == 4)
  133.                 spin = 0;
  134. #endif
  135.         }
  136.     }
  137.  
  138.     return false;
  139. }
  140.  
  141. static void reset_board(void)
  142. {
  143.     byte        row, col, i;
  144.  
  145.     for (row = 0; row < ORDER; ++row)
  146.         for (col = 0; col < ORDER; ++col)
  147.             board[row][col] = 0;
  148.  
  149.     for (i = 0; i < ORDER * ORDER + 1; ++i)
  150.         used[i] = false;
  151. }
  152. int main(void)
  153. {                               /*int argc, char **argv) */
  154. #if 0
  155.     if (argc != 2) {
  156.         fprintf(stderr, "usage: magic order\n");
  157.         return 1;
  158.     }
  159. #endif
  160.  
  161.     reset_board();
  162.     if (solve(0, 0))
  163.         print_board();
  164.     else
  165.         printf("There were no solutions for your board\n");
  166.  
  167.     return 0;
  168. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement