Advertisement
AyrA

Sudoku solver

May 4th, 2015
888
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.66 KB | None | 0 0
  1. //Sudoku solver created by Singapore's Prime Minister Lee Hsien Loong
  2. //I did some small changes so it compiles with pedantic settings and Wextra, Wall, Werror
  3.  
  4. #include "stdio.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.  
  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 = 0;
  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.      PrintArray();
  96. }
  97.  
  98.  
  99. void PrintStats()
  100. {
  101.     int i, S;
  102.  
  103.     printf("\nLevel Counts:\n\n");
  104.  
  105.     S = 0;
  106.     while (LevelCount[S] == 0) S++;
  107.  
  108.     i = 0;
  109.  
  110.     while (S < 81) {
  111.           int Seq = Sequence[S];
  112.           printf("(%d, %d):%4d ", Seq / 9 + 1, Seq % 9 + 1, LevelCount[S]);
  113.           if (i++ > 4){
  114.              printf("\n");
  115.              i = 0;
  116.           }
  117.           S++;
  118.     }
  119.  
  120.     printf("\n\nCount = %d\n", Count);
  121. }
  122.  
  123.  
  124. void Succeed()
  125. {
  126.      PrintArray();
  127.      PrintStats();
  128. }
  129.  
  130.  
  131. int NextSeq(int S)
  132. {
  133.     int S2 = 0, Square, Possibles, BitCount;
  134.     int T, MinBitCount = 100;
  135.  
  136.     for (T = S; T < 81; T++) {
  137.         Square = Sequence[T];
  138.         Possibles = Block[InBlock[Square]] & Row[InRow[Square]] & Col[InCol[Square]];
  139.         BitCount = 0;
  140.         while (Possibles) {
  141.            Possibles &= ~(Possibles & -Possibles);
  142.            BitCount++;
  143.         }
  144.  
  145.         if (BitCount < MinBitCount) {
  146.            MinBitCount = BitCount;
  147.            S2 = T;
  148.         }
  149.     }
  150.  
  151.     return S2;
  152. }
  153.  
  154.  
  155. void Place(int S)
  156. {
  157.     LevelCount[S]++;
  158.     Count++;
  159.  
  160.     if (S >= 81) {
  161.        Succeed();
  162.        return;
  163.     }
  164.  
  165.     int S2 = NextSeq(S);
  166.     SwapSeqEntries(S, S2);
  167.  
  168.     int Square = Sequence[S];
  169.  
  170.     int     BlockIndex = InBlock[Square],
  171.             RowIndex = InRow[Square],
  172.             ColIndex = InCol[Square];
  173.  
  174.     int     Possibles = Block[BlockIndex] & Row[RowIndex] & Col[ColIndex];
  175.     while (Possibles) {
  176.           int valbit = Possibles & (-Possibles); // Lowest 1 bit in Possibles
  177.           Possibles &= ~valbit;
  178.           Entry[Square] = valbit;
  179.           Block[BlockIndex] &= ~valbit;
  180.           Row[RowIndex] &= ~valbit;
  181.           Col[ColIndex] &= ~valbit;
  182.                
  183.           Place(S + 1);
  184.  
  185.           Entry[Square] = BLANK; // Could be moved out of the loop
  186.           Block[BlockIndex] |= valbit;
  187.           Row[RowIndex] |= valbit;
  188.           Col[ColIndex] |= valbit;
  189.     }
  190.  
  191.     SwapSeqEntries(S, S2);
  192. }
  193.  
  194.  
  195. int main()
  196. {
  197.     int i, j, Square;
  198.  
  199.     for (i = 0; i < 9; i++)
  200.         for (j = 0; j < 9; j++) {
  201.             Square = 9 * i + j;
  202.             InRow[Square] = i;
  203.             InCol[Square] = j;
  204.             InBlock[Square] = (i / 3) * 3 + ( j / 3);
  205.         }
  206.  
  207.  
  208.     for (Square = 0; Square < 81; Square++) {
  209.         Sequence[Square] = Square;
  210.         Entry[Square] = BLANK;
  211.         LevelCount[Square] = 0;
  212.     }
  213.  
  214.     for (i = 0; i < 9; i++)
  215.         Block[i] = Row[i] = Col[i] = ONES;
  216.  
  217.     ConsoleInput();
  218.     Place(SeqPtr);
  219.     printf("\n\nTotal Count = %d\n", Count);
  220.  
  221.     return 0;
  222. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement