Advertisement
Guest User

sudokusolver

a guest
Sep 20th, 2023
499
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.79 KB | None | 0 0
  1. /******************************************************************************
  2.  
  3. Welcome to GDB Online.
  4.   GDB online is an online compiler and debugger tool for C, C++, Python, PHP, Ruby,
  5.   C#, OCaml, VB, Perl, Swift, Prolog, Javascript, Pascal, COBOL, HTML, CSS, JS
  6.   Code, Compile, Run and Debug online from anywhere in world.
  7.  
  8. *******************************************************************************/
  9. #include <stdio.h>
  10. unsigned char* sudoku_src = "700000400020070080003008079900500300060020090001097006000300900030040060009001035";
  11. //"001093000006000800070200051800040200400801006007050008920004010005000900000930500";
  12. /*"001007090\
  13. 590080001\
  14. 030000080\
  15. 000005800\
  16. 050060020\
  17. 004100000\
  18. 080000030\
  19. 100020079\
  20. 020700400";*/
  21. enum sudoku_values{
  22.     one = 1,
  23.     two = one << 1,
  24.     three = two << 1,
  25.     four = three << 1,
  26.     five = four << 1,
  27.     six = five << 1,
  28.     seven = six << 1,
  29.     eight = seven << 1,
  30.     nine = eight << 1,
  31.     all = one | two | three | four | five | six | seven | eight | nine
  32. };
  33. static enum sudoku_values map_char_to_sudoku_value[255] =
  34. {
  35.     ['0'] = all,
  36.     ['1'] = one,
  37.     ['2'] = two,
  38.     ['3'] = three,
  39.     ['4'] = four,
  40.     ['5'] = five,
  41.     ['6'] = six,
  42.     ['7'] = seven,
  43.     ['8'] = eight,
  44.     ['9'] = nine,
  45. };
  46. static char sudoku_value_char_to_char[1024] =
  47. {
  48.     [all] = '0',
  49.     [one] = '1',
  50.     [two] = '2',
  51.     [three] = '3',
  52.     [four] = '4',
  53.     [five] = '5',
  54.     [six] = '6',
  55.     [seven] = '7',
  56.     [eight] = '8',
  57.     [nine] = '9',
  58. };
  59. int square_index(int row_col){
  60.     return 3 * (row_col / 3);//integer division floors
  61. }
  62.  
  63. typedef struct sudoku_pair{
  64.     int row;
  65.     int col;
  66.     int value;
  67. }sudoku_pair;
  68. typedef struct sudoku{
  69.     union{
  70.     int roster[9][9];
  71.     int roster_line[81];
  72.     };
  73.     // flag[i] == 0: to be considered this
  74.     // flag[i] == 1: never consider
  75.     union{
  76.     int roster_flags[9][9];
  77.     int roster_flags_line[88];
  78.     };
  79.     int N;
  80.     sudoku_pair stack[81];
  81. }sudoku;
  82. sudoku new_sudoku(){
  83.     sudoku rv;
  84.     for(int i = 0 ; i < 81; i++)
  85.         rv.roster_line[i] = all;
  86.     return rv;
  87. }
  88. sudoku sudoku_from_string(unsigned char* source){
  89.     sudoku rv = {0};
  90.     int* values = (rv.roster_line);
  91.    
  92.     while(*source)
  93.         *values++ = map_char_to_sudoku_value[*source++];
  94.     for(int i = 0; i < 9;i++)
  95.         for(int j = 0; j < 9;j++)
  96.             if(rv.roster[i][j] != all){
  97.                 rv.stack[rv.N++] = (sudoku_pair){i,j,rv.roster[i][j]};
  98.                 rv.roster_flags[i][j] = 1;
  99.             }
  100.                
  101.     return rv;
  102. }
  103. void print_sudoku(sudoku s){
  104.     for(int i = 0 ; i < 81; i++)
  105.         printf("%s%c", (i%9 == 0)?"\n":"", sudoku_value_char_to_char[s.roster_line[i]] );
  106. }
  107.  
  108. void remove_value_from_row(sudoku* s, int row, int bit_filter){
  109.     for(int col = 0; col < 9; col++)
  110.         s->roster[row][col] &= bit_filter;
  111. }
  112. void remove_value_from_col(sudoku* s, int col, int bit_filter){
  113.     for(int row = 0; row < 9; row++)
  114.         s->roster[row][col] &= bit_filter;
  115. }
  116. void remove_value_from_square(sudoku* s, int square_row,int square_col, int bit_filter){
  117.     for(int row = square_row; row < square_row + 3; row++)
  118.         for(int col = square_col; col < square_col + 3; col++)
  119.            s->roster[row][col] &= bit_filter;
  120. }
  121. void remove_value_from_sudoku(sudoku* s,sudoku_pair pair){
  122.     int row = pair.row;
  123.     int col = pair.col;
  124.     enum sudoku_values val = pair.value;
  125.     int  bit_filter = all & (~val);
  126.     remove_value_from_row(s,row,bit_filter);
  127.     remove_value_from_col(s,col,bit_filter);
  128.     remove_value_from_square(s,square_index(row),square_index(col),bit_filter);
  129.     s->roster[row][col] = val;
  130. }
  131.  
  132. void partial_solve(sudoku* s){
  133.     do{
  134.         for(int i = 0 ; i < s->N; i++)
  135.             remove_value_from_sudoku(s,s->stack[i]);
  136.         s->N=0;
  137.         for(int i = 0; i < 9;i++)
  138.             for(int j = 0; j < 9;j++)
  139.                 {
  140.                     if(s->roster_flags[i][j])
  141.                         continue;
  142.                     int val = s->roster[i][j];
  143.                     if(val == 0){
  144.                         //printf("\nunsolvable i %i, j %i\n",i,j);
  145.                         goto unsolvable;
  146.                     }
  147.                     if(val == one || val == two || val == three || val == four || val == five || val == six || val == seven || val == eight || val == nine)
  148.                         {  
  149.                             s->stack[s->N++] = (sudoku_pair){i,j,val};
  150.                             s->roster_flags[i][j] = 1;
  151.                         }
  152.                 }
  153.     }while(s->N);
  154.     unsolvable:;
  155. }
  156. static int sudoku_count;
  157. static sudoku sudoku_stack[1000];
  158. void branch_sudoku(sudoku* s){
  159.  //   printf("\nbranches:%i\n",sudoku_count);
  160.     for(int i = 0; i < 9;i++)
  161.         for(int j = 0; j < 9;j++)
  162.             if(s->roster_flags[i][j] == 0){
  163.                 for(int val = 0; val < 9 ; val++)
  164.                     if(s->roster[i][j] & (1 << val)){
  165.                         sudoku_stack[sudoku_count] = *s;
  166.                         sudoku_stack[sudoku_count].roster[i][j] = (1 << val);
  167.                         sudoku_stack[sudoku_count].stack[sudoku_stack[sudoku_count].N++] = (sudoku_pair){i, j,  1 << val};
  168.                         sudoku_count++;
  169.                     }
  170.                     return;
  171.             }
  172.        
  173. }
  174. int solved(sudoku* s){
  175.     int rv=1;
  176.     for(int i =0;i<81;i++)
  177.         rv &= s->roster_flags_line[i];
  178.     return rv;
  179. }
  180. int main()
  181. {
  182.     sudoku s = sudoku_from_string(sudoku_src);
  183.     sudoku_stack[sudoku_count++] = s;
  184.    
  185.     print_sudoku(s);
  186.     while(sudoku_count){
  187.         s = sudoku_stack[--sudoku_count];
  188.         partial_solve(&s);
  189.         if(solved(&s))
  190.             break;
  191.         else
  192.             branch_sudoku(&s);
  193.     }
  194.    print_sudoku(s);
  195.     return 0;
  196. }
  197.  
  198.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement