1 / 18

CS 410 Mastery in Programming Chapter 10 Hints for Simple Sudoku

Herbert G. Mayer, PSU CS Status 7/29/2013. CS 410 Mastery in Programming Chapter 10 Hints for Simple Sudoku. Syllabus. Requirements Level 0 Level 0 Algorithm Data Structure Check Row, Columns Check Subsquares L0 Sudoku Sample References. Requirements.

kesia
Download Presentation

CS 410 Mastery in Programming Chapter 10 Hints for Simple Sudoku

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Herbert G. Mayer, PSU CS Status 7/29/2013 CS 410Mastery in ProgrammingChapter 10Hints for Simple Sudoku

  2. Syllabus • Requirements • Level 0 • Level 0 Algorithm • Data Structure • Check Row, Columns • Check Subsquares • L0 Sudoku • Sample • References

  3. Requirements • The Sudoku game has a starting board Sstart • Sstart must be solvable, leading to a fully populated Sudoku board Send • The situation must be uniquely solvable; i.e. Sstart may not be open-ended so that multiple solutions Send will be possible; that would be interesting too, but is ambiguous • Send must be reachable without backtracking. I.e. it will not be necessary to discard an intermediate situation Sinter since it fails to produce a solution, and then to continue where Sinter has left off; backtracking is an option to pursue, but is not required for our assumed unique, deterministic situations • If a violating Sstart is encountered, the game cannot be solved with the programs proposed here; program aborts

  4. Level 0 Implement a simple Sudoku solution that uses solely the requirements for all rows, all columns, and all subsquares. Sometimes this leads to a solution, which we name level0 Sudoku Other solvable situation are of higher level Initially we solely focus on level0 start situations Sstart

  5. Level 0 Algorithm Precondition: • Have an initial Sudoku board that is: • Incomplete, i.e. not all fields are populated • But has some fields filled in, but in a way to let the game be uniquely and deterministically solvable • Without contradictions, i.e.: • No row holds the same number more than once • No column holds the same number more than once • No sub-square holds the same number more than once Initial Steps: • For each empty field, i.e. that has no defined number: • Set all possible candidate numbers in some data structure • The list of all candidate numbers for a 3*3 by 3*3 Sudoku is: 1, 2, 3, 4, 5, 6, 7, 8, 9

  6. Level 0 Algorithm • Step1: Set “changes” to 0 • Step2: For every undefined sudoku[row][col] field, i.e. that has candidates in subset of { 1, 2, 3, 4, 5, 6, 7, 8, 9 } • For any number n found on same “row”, remove n from the candidate list • This is reminiscent of “Sieve if Eratosthenes” • For any number n found on same “column”, remove n from the candidate list, if not already gone • For any number n found in the same “sub-square”, remove n from the candidate list, if not already gone • if the candidate list of sudoku[row][col] is down to 1, then • changes++ • Set the field sudoku[row][col] to the sole remaining number that is left • Step 3: go to step 1 until “changes” is 0 • i.e. we go though all fields sudoku[row][col] repeatedly, as long as we see changes • Step 4: If all 3*3 by 3*3 fields are set: print success and output the whole board; else the initial field is not a level 0 solvable situation

  7. Data Structure 1 • #define BIG_N ( SMALL_N * SMALL_N ) • #define EOL '\n' • #define EMPTY 0 • #define NO_CHAR ' ' • #define FALSE 0 • #define TRUE 1 • #define P_BAR printf( "|" ) • #define P_LINE printf( "-" ) • #define P_PLUS printf( "+" ) • #define P_EOL printf( "\n" ) • #define P_TAB printf( "\t" ) • #define P_BLANK printf( " " )

  8. Data Structure 2 • // each element of an n*n X n*n sudoku board has the following structure: • // "field" has any of the values 0..n*n, with 0 meaning that it is empty. • // "option_count" states: how many of n*n numbers could be options. • // "can_be[]" is array of n*n+1 bools. Says whether element "i" is option • // if can_be[i] is false, number "i" cannot be option any longer. • // if option_count ever reaches 1, then we "know" the field value • // General data structure layout • // 0 1 2 3 8 9 • // +-----+ +-----+ +-----+-----+-----+-----+- ... -+-----+-----+ • // | NAT | | NAT | | DC | | | | ... | | | • // +-----+ +-----+ +-----+-----+-----+-----+- ... -+-----+-----+ • // field option_count can_be[ BIG_N + 1 ] • // int int bool

  9. Data Structure 3 • // specific layout for empty field • // 0 1 2 3 8 9 • // +-----+ +-----+ +-----+-----+-----+-----+- ... -+-----+-----+ • // | 0 | | 9 | | DC | T | T | T | ... | T | T | • // +-----+ +-----+ +-----+-----+-----+-----+- ... -+-----+-----+ • // field option_count can_be[ BIG_N + 1 ] • // • // Specific layout for occupied field 3 • // 0 1 2 3 8 9 • // +-----+ +-----+ +-----+-----+-----+-----+- ... -+-----+-----+ • // | 3 | | 0 | | DC | F | F | T | ... | F | F | • // +-----+ +-----+ +-----+-----+-----+-----+- ... -+-----+-----+ • // field option_count can_be[ BIG_N + 1 ] • // • typedef struct board_tp • { • unsigned field; // 0 if empty, else one of 1..n*n • unsigned option_count; // initially, all n*n are options • unsigned can_be[ BIG_N + 1 ]; // if false, number "i" impossible • } struct_board_tp;

  10. Data Structure 4 • //////////////////////////////////////////////////////////////////////// • //////////////////////////////////////////////////////////////////////// • //////////// //////////// • //////////// G l o b a l O j e c t s //////////// • //////////// //////////// • //////////////////////////////////////////////////////////////////////// • //////////////////////////////////////////////////////////////////////// • // this is the complete sudoku board, n*n by n*n = BIG_N * BIG_N fields • struct_board_tp sudoku[ BIG_N ][ BIG_N ];

  11. Check Rows, Columns // check all horizontal and vertical lines for empty spaces. // each empty space initially has BIG_N options // but for each existing value in that row or col, decrease the option. // if per chance the options end up just 1, then we can plug in a number. // return the number of fields changed from empty to a new value unsigned horiz_vert( row_col_anal_tprow_or_col ) { // horiz_vert unsigned changes = 0; unsigned options = 0; unsigned field = 0; // remember the next number to be excluded for ( int row = 0; row < BIG_N; row++ ) { for ( int col = 0; col < BIG_N; col++ ) { if ( SRC.field ) { // there is a number ASSERT( ( SRC.option_count == 0 ), "has # + option?" ); }else{ // field is EMPTY. Goal to count down options to 1 ASSERT( ( SRC.option_count ), "0 field must have opt" ); // go thru each field. For # found, exclude # from can_be[] for ( int i = 0; i < BIG_N; i++ ) { // continued on next page . . .

  12. Check Rows, Columns // . . . continued from previous page // go thru each field. For # found, exclude # from can_be[] for ( int i = 0; i < BIG_N; i++ ) { if ( row_or_col == row_analysis ) { field = sudoku[ row ][ i ].field; }else{ // column analysis field = sudoku[ i ][ col ].field; } //end if if ( field ) { // we found a field SRC.can_be[ field ] = FALSE; } //end if SRC.option_count = options = count_fields( row, col ); if ( options == 1 ) { // plug in only 1 of BIG_N numbers // and set option_count to 0 field = find_1_field( row, col ); FILL(); } //end if } //end for i } //end if } //end for col } //end for row return changes; } //end horiz_vert

  13. Check Subsquare • // check all horizontal and vertical lines for empty spaces. • // each empty space initially has BIG_N options • // But for each field value in subsquare, decrease options. • // if per chance the options end up just 1, then we can plug in a number. • // return the number of fields changed from empty to a new value • unsigned subsquare( ) • { // subsquare • unsigned changes = 0; • unsigned options = 0; • unsigned field = 0; // remember the next number to be excluded • for ( int row = 0; row < BIG_N; row++ ) { • for ( int col = 0; col < BIG_N; col++ ) { • if ( SRC.field ) { // there is a number • ASSERT( ( SRC.option_count == 0 ), "has # + option?" ); • }else{ • // field is EMPTY. Goal to count down options to 1 • ASSERT( ( SRC.option_count ), "subsquare must have opt" ); • // analyze all fields in subsquare, exclude from can_be[] • for ( int i = f( row ); i < ( f( row ) + SMALL_N ); i++ ) { • ASSERT( ( i <= row+SMALL_N ), "wrong i_row in [][]" ); • // continue on next page

  14. Check Subsquare • // continued from previous page . . . • for ( int i = f( row ); i < ( f( row ) + SMALL_N ); i++ ) { • ASSERT( ( i <= row+SMALL_N ), "wrong i_row in [][]" ); • for ( int j = f( col ); j < ( f( col ) + SMALL_N ); j++ ) { • ASSERT( j <= col+SMALL_N, "wrong j_col in [][]" ); • field = sudoku[ i ][ j ].field; • if ( field ) { • // we found a non-zero field • SRC.can_be[ field ] = FALSE; • } //end if • SRC.option_count = options = count_fields( row, col ); • if ( options == 1 ) { • // plug in only 1 of BIG_N numbers • // and set option_count to 0 • field = find_1_field( row, col ); • FILL(); • } //end if • } //end for j • } //end for i • } //end if • } //end for col • } //end for row • return changes; • } //end subsquare

  15. L0 Sudoku // simplest sudoku strategy by eliminating options for a field // that would conflict with existing numbers in row, column, subsquare unsigned sudoku_level0() { //sudoku_level0 unsigned changes; // count fields filled in unsigned iterations = 0; // count times we go around unsigned errors = 0; // do final sanity check do { changes = 0; changes = horiz_vert( row_analysis ); changes += horiz_vert( col_analysis ); changes += subsquare(); ++iterations; } while ( changes ); try_single_option(); # ifdef DEBUG printf( "Iterated level0 %d times.\n", iterations ); errors = sanity_check(); # endif // DEBUG return changes; } //end sudoku_level0

  16. Sample Input After setting initial fields sudoku board. 0 1 2 3 4 5 6 7 8 +------+------+------+ | 4 1| 5| 2 | 0 | 6 7| 3 | 8 5 | 1 | 5 3| 7 | 1 | 2 +------+------+------+ | 8 | 2 4 3| | 3 | | 9| 1| 4 | 4| 8 | 2| 5 +------+------+------+ | 3 | 6| 9 | 6 | | 2 | 5 8| 7 | 7 | 9 | 6| 8 +------+------+------+ Statistics initially: Total # of fields: 81 Fields filled: 31 empty fields: 50

  17. Sample Output Sudoku level 0 sudoku board. 0 1 2 3 4 5 6 7 8 +------+------+------+ | 4 9 1| 6 8 5| 2 7 3| 0 | 6 2 7| 3 9 1| 8 5 4| 1 | 8 5 3| 4 7 2| 6 1 9| 2 +------+------+------+ | 1 8 9| 2 4 3| 7 6 5| 3 | 7 3 2| 5 6 9| 4 8 1| 4 | 5 6 4| 8 1 7| 3 9 2| 5 +------+------+------+ | 3 4 8| 1 5 6| 9 2 7| 6 | 9 1 6| 7 2 4| 5 3 8| 7 | 2 7 5| 9 3 8| 1 4 6| 8 +------+------+------+ Statistics Sudoku level 0 Total # of fields: 81 Fields filled: 81 empty fields: 0 Field was solvable with level 0

  18. References • Here you may play: http://www.websudoku.com/ • The rules: http://en.wikipedia.org/wiki/Sudoku • History: http://www.sudokucentral.com/what-is-sudoku • C Solution: http://www.daniweb.com/software-development/cpp/threads/48788

More Related