Advertisement
Razali

PM Lee's Sudoku Solver

Aug 8th, 2015
248
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.11 KB | None | 0 0
  1. #pragma warning(disable:4996)
  2.  
  3. #include "stdio.h"
  4. #include "time.h"
  5.  
  6.  
  7. int InBlock[81], InRow[81], InCol[81];
  8.  
  9. const int BLANK = 0;
  10. const int ONES = 0x3fe;     // Binary 1111111110
  11.  
  12. int Entry[81];  // Records entries 1-9 in the grid, as the corresponding bit set to 1
  13. int Block[9], Row[9], Col[9];   // Each int is a 9-bit array
  14.  
  15. int SeqPtr = 0;
  16. int Sequence[81];
  17.  
  18. int Count = 0;
  19. int LevelCount[81];
  20.  
  21. clock_t begin, end;
  22. void SwapSeqEntries(int S1, int S2)
  23. {
  24.     int temp = Sequence[S2];
  25.     Sequence[S2] = Sequence[S1];
  26.     Sequence[S1] = temp;
  27. }
  28.  
  29.  
  30. void InitEntry(int i, int j, int val)
  31. {
  32.     int Square = 9 * i + j;
  33.     int valbit = 1 << val;
  34.     int SeqPtr2;
  35.  
  36.     // add suitable checks for data consistency
  37.  
  38.     Entry[Square] = valbit;
  39.     Block[InBlock[Square]] &= ~valbit;
  40.     Col[InCol[Square]] &= ~valbit; // Simpler Col[j] &= ~valbit;
  41.     Row[InRow[Square]] &= ~valbit; // Simpler Row[i] &= ~valbit;
  42.  
  43.     SeqPtr2 = SeqPtr;
  44.     while (SeqPtr2 < 81 && Sequence[SeqPtr2] != Square)
  45.         SeqPtr2++;
  46.  
  47.     SwapSeqEntries(SeqPtr, SeqPtr2);
  48.     SeqPtr++;
  49. }
  50.  
  51.  
  52. void PrintArray()
  53. {
  54.     int i, j, valbit, val, Square;
  55.     char ch;
  56.  
  57.     Square = 0;
  58.  
  59.     for (i = 0; i < 9; i++) {
  60.         if (i % 3 == 0) putc('\n', stdout);
  61.         for (j = 0; j < 9; j++) {
  62.             if (j % 3 == 0) putc(' ', stdout);
  63.             valbit = Entry[Square++];
  64.             if (valbit == 0) ch = '-';
  65.             else {
  66.                 for (val = 1; val <= 9; val++)
  67.                     if (valbit == (1 << val)) {
  68.                         ch = '0' + val;
  69.                         break;
  70.                     }
  71.             }
  72.             putc(ch, stdout);
  73.         }
  74.         putc('\n', stdout);
  75.     }
  76. }
  77.  
  78.  
  79. void ConsoleInput()
  80. {
  81.     int i, j;
  82.     char InputString[80];
  83.  
  84.     for (i = 0; i < 9; i++) {
  85.         printf("Row[%d] : ", i + 1);
  86.         scanf("%s", InputString);
  87.  
  88.         for (j = 0; j < 9; j++) {
  89.             char ch = InputString[j];
  90.             if (ch >= '1' && ch <= '9')
  91.                 InitEntry(i, j, ch - '0');
  92.         }
  93.     }
  94.  
  95.     begin = clock();
  96.  
  97.     PrintArray();
  98. }
  99.  
  100.  
  101. void PrintStats()
  102. {
  103.     int i, j, S;
  104.  
  105.     printf("\nLevel Counts:\n\n");
  106.  
  107.     S = 0;
  108.     while (LevelCount[S] == 0) S++;
  109.  
  110.     i = 0;
  111.  
  112.     while (S < 81) {
  113.         int Seq = Sequence[S];
  114.         printf("(%d, %d):%4d ", Seq / 9 + 1, Seq % 9 + 1, LevelCount[S]);
  115.         if (i++ > 4){
  116.             printf("\n");
  117.             i = 0;
  118.         }
  119.         S++;
  120.     }
  121.  
  122.     printf("\n\nCount = %d\n", Count);
  123. }
  124.  
  125.  
  126. void Succeed()
  127. {
  128.     PrintArray();
  129.     PrintStats();
  130. }
  131.  
  132.  
  133. int NextSeq(int S)
  134. {
  135.     int S2, Square, Possibles, BitCount;
  136.     int T, MinBitCount = 100;
  137.  
  138.     for (T = S; T < 81; T++) {
  139.         Square = Sequence[T];
  140.         Possibles = Block[InBlock[Square]] & Row[InRow[Square]] & Col[InCol[Square]];
  141.         BitCount = 0;
  142.         while (Possibles) {
  143.             Possibles &= ~(Possibles & -Possibles);
  144.             BitCount++;
  145.         }
  146.  
  147.         if (BitCount < MinBitCount) {
  148.             MinBitCount = BitCount;
  149.             S2 = T;
  150.         }
  151.     }
  152.  
  153.     return S2;
  154. }
  155.  
  156.  
  157. void Place(int S)
  158. {
  159.     LevelCount[S]++;
  160.     Count++;
  161.  
  162.     if (S >= 81) {
  163.         Succeed();
  164.         return;
  165.     }
  166.  
  167.     int S2 = NextSeq(S);
  168.     SwapSeqEntries(S, S2);
  169.  
  170.     int Square = Sequence[S];
  171.  
  172.     int     BlockIndex = InBlock[Square],
  173.         RowIndex = InRow[Square],
  174.         ColIndex = InCol[Square];
  175.  
  176.     int     Possibles = Block[BlockIndex] & Row[RowIndex] & Col[ColIndex];
  177.     while (Possibles) {
  178.         int valbit = Possibles & (-Possibles); // Lowest 1 bit in Possibles
  179.         Possibles &= ~valbit;
  180.         Entry[Square] = valbit;
  181.         Block[BlockIndex] &= ~valbit;
  182.         Row[RowIndex] &= ~valbit;
  183.         Col[ColIndex] &= ~valbit;
  184.  
  185.         Place(S + 1);
  186.  
  187.         Entry[Square] = BLANK; // Could be moved out of the loop
  188.         Block[BlockIndex] |= valbit;
  189.         Row[RowIndex] |= valbit;
  190.         Col[ColIndex] |= valbit;
  191.     }
  192.  
  193.     SwapSeqEntries(S, S2);
  194. }
  195.  
  196.  
  197. int main(int argc, char* argv[])
  198. {
  199.     int i, j, Square;
  200.  
  201.     for (i = 0; i < 9; i++)
  202.         for (j = 0; j < 9; j++) {
  203.             Square = 9 * i + j;
  204.             InRow[Square] = i;
  205.             InCol[Square] = j;
  206.             InBlock[Square] = (i / 3) * 3 + (j / 3);
  207.         }
  208.  
  209.  
  210.     for (Square = 0; Square < 81; Square++) {
  211.         Sequence[Square] = Square;
  212.         Entry[Square] = BLANK;
  213.         LevelCount[Square] = 0;
  214.     }
  215.  
  216.     for (i = 0; i < 9; i++)
  217.         Block[i] = Row[i] = Col[i] = ONES;
  218.  
  219.     ConsoleInput();
  220.  
  221.    
  222.     double time_spent;
  223.    
  224.        
  225.     Place(SeqPtr);
  226.  
  227.     end = clock();
  228.     time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
  229.  
  230.     printf("\n\nTotal Count = %d\n", Count);
  231.  
  232.     printf("\n\nTotal time taken: %lf", time_spent);
  233.  
  234.     getch();
  235.     return 0;
  236. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement