Thread: 3 dimentional arrays

  1. #31
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    it would help i think if the hidden singles function starting on line 187 searched the regions as well like i do on line 153 for naked singles

  2. #32
    Registered User
    Join Date
    Dec 2017
    Posts
    1,633
    The NakedSingles function doesn't seem to need the different scan types. Any one of the three seems to do the trick. See the part I commented out in that function.

    I implemented a region scan in the HiddenSingles function which seems to solve the puzzle that wasn't solved before.
    However, I've added a few other puzzles that the program still does not solve.

    I also changed the spelling of "Soloution" to "Solution".
    Code:
    #include <stdio.h>
    #include <stdlib.h>
     
    void RemovePossNum(int, int, int, int [][9][9] );
    void GetRegion( int, int, int *, int * );
    void RemoveNumRegion( int, int, int, int [][9][9] );
    void printSolution(int [][9] );
    void printPossibleNumbers( int [][9][9] );
    void SolvedCell( int, int, int, int [][9][9], int [][9] );
    int NakedSingles( int [][9][9], int [][9] );
    int FindNakedSingle( int, int, int [][9][9], int [][9] );
    int HiddenSingles( int [][9][9], int [][9] );
    void FindHiddenSingles( int, int, int *, int [][9][9], int [][9] );
    int GetHiddenSingles( int, int, int *, int [][9][9], int [][9] );
     
    int main()
    {
        int PossibleNums[9][9][9] = {{{ 0 }}};
     
        int Solution[9][9] = {
     
    // You can set the PUZ here or comment out this define and set
    // PUZ from the command line with, e.g., -DPUZ=5
    #define PUZ 0
     
    #if PUZ == 0
            { 0, 0, 0, 0, 0, 0, 0, 1, 0 },
            { 4, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 2, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 5, 0, 4, 0, 7 },
            { 0, 0, 8, 0, 0, 0, 3, 0, 0 },
            { 0, 0, 1, 0, 9, 0, 0, 0, 0 },
            { 3, 0, 0, 4, 0, 0, 2, 0, 0 },
            { 0, 5, 0, 1, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 8, 0, 6, 0, 0, 0 }
    #elif PUZ == 1
            { 0, 0, 0, 5, 0, 6, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 6, 2 },
            { 7, 0, 4, 0, 1, 0, 0, 0, 0 },
            { 9, 0, 0, 0, 4, 3, 0, 0, 7 },
            { 0, 2, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 8, 0, 0, 9, 0, 0, 5, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 3, 0, 0, 0, 0, 8, 7, 0, 0 },
            { 0, 5, 0, 3, 0, 4, 0, 0, 1 }
    #elif PUZ == 2
            { 0, 9, 3, 4, 7, 0, 0, 6, 0 },
            { 0, 8, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 6, 0, 0, 0, 0, 1 },
            { 8, 0, 0, 0, 0, 0, 0, 3, 0 },
            { 0, 3, 4, 0, 0, 9, 0, 0, 5 },
            { 1, 0, 0, 0, 4, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 5, 2, 0, 0 },
            { 0, 6, 7, 0, 9, 0, 0, 1, 0 },
            { 4, 0, 0, 0, 0, 0, 0, 0, 0 }
    #elif PUZ == 3
            { 3, 0, 0, 2, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 1, 0, 7, 0, 0, 0 },
            { 7, 0, 6, 0, 3, 0, 5, 0, 0 },
            { 0, 7, 0, 0, 0, 9, 0, 8, 0 },
            { 9, 0, 0, 0, 2, 0, 0, 0, 4 },
            { 0, 1, 0, 8, 0, 0, 0, 5, 0 },
            { 0, 0, 9, 0, 4, 0, 3, 0, 1 },
            { 0, 0, 0, 7, 0, 2, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 8, 0, 0, 6 }
    #elif PUZ == 4
            { 0, 0, 0, 0, 0, 0, 0, 1, 2 },
            { 0, 0, 8, 0, 3, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 4, 0 },
            { 1, 2, 0, 5, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 4, 7, 0, 0 },
            { 0, 6, 0, 0, 0, 0, 0, 0, 0 },
            { 5, 0, 7, 0, 0, 0, 3, 0, 0 },
            { 0, 0, 0, 6, 2, 0, 0, 0, 0 },
            { 0, 0, 0, 1, 0, 0, 0, 0, 0 }
    #elif PUZ == 5
            { 0, 0, 0, 0, 0, 0, 0, 1, 2 },
            { 0, 5, 0, 4, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 3, 0 },
            { 7, 0, 0, 6, 0, 0, 4, 0, 0 },
            { 0, 0, 1, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 8, 0, 0, 0, 0 },
            { 9, 2, 0, 0, 0, 0, 8, 0, 0 },
            { 0, 0, 0, 5, 1, 0, 7, 0, 0 },
            { 0, 0, 0, 0, 0, 3, 0, 0, 0 }
    #elif PUZ == 6
            { 0, 0, 0, 0, 0, 0, 0, 1, 2 },
            { 3, 0, 0, 0, 0, 0, 0, 6, 0 },
            { 0, 0, 0, 0, 4, 0, 0, 0, 0 },
            { 9, 0, 0, 0, 0, 0, 5, 0, 0 },
            { 0, 0, 0, 0, 0, 1, 0, 7, 0 },
            { 0, 2, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 3, 5, 0, 4, 0, 0 },
            { 0, 0, 1, 4, 0, 0, 8, 0, 0 },
            { 0, 6, 0, 0, 0, 0, 0, 0, 0 }
    #elif PUZ == 7
            { 0, 0, 0, 0, 0, 0, 0, 1, 2 },
            { 4, 0, 0, 0, 9, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 5, 0 },
            { 0, 7, 0, 2, 0, 0, 0, 0, 0 },
            { 6, 0, 0, 0, 0, 0, 4, 0, 0 },
            { 0, 0, 0, 1, 0, 8, 0, 0, 0 },
            { 0, 1, 8, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 3, 0, 7, 0, 0 },
            { 5, 0, 2, 0, 0, 0, 0, 0, 0 }
    #elif PUZ == 8
            { 0, 0, 0, 0, 0, 0, 0, 1, 2 },
            { 5, 0, 0, 0, 0, 8, 0, 0, 0 },
            { 0, 0, 0, 7, 0, 0, 0, 0, 0 },
            { 6, 0, 0, 1, 2, 0, 0, 0, 0 },
            { 7, 0, 0, 0, 0, 0, 4, 5, 0 },
            { 0, 0, 0, 0, 3, 0, 0, 0, 0 },
            { 0, 3, 0, 0, 0, 0, 8, 0, 0 },
            { 0, 0, 0, 5, 0, 0, 7, 0, 0 },
            { 0, 2, 0, 0, 0, 0, 0, 0, 0 }
    #elif PUZ == 9
            { 0, 0, 0, 0, 0, 0, 0, 1, 2 },
            { 7, 0, 0, 0, 6, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 5, 0 },
            { 0, 8, 0, 2, 0, 0, 0, 0, 0 },
            { 6, 0, 0, 0, 0, 0, 4, 0, 0 },
            { 0, 0, 0, 1, 0, 9, 0, 0, 0 },
            { 0, 1, 9, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 3, 0, 8, 0, 0 },
            { 5, 0, 2, 0, 0, 0, 0, 0, 0 }
    #endif
        };
     
        for ( int i = 0; i < 9; i++ )
            for ( int j = 0; j < 9; j++ )
                if ( Solution[i][j] == 0 )
                    for ( int k = 0; k < 9; k++ )
                        PossibleNums[i][j][k] = k + 1;
     
        //printPossibleNumbers(PossibleNums);
        int NumcellsSolved = 0;
     
        for ( int i = 0; i < 9; i++ )
            for ( int j = 0; j < 9; j++ )
                if ( Solution[i][j] )
                {
                    RemovePossNum( i, j, Solution[i][j], PossibleNums );
                    NumcellsSolved++;
                }
     
        printSolution( Solution );
        printf("number of solved cells is %d\n", NumcellsSolved);
     
        while (NumcellsSolved < 81 )
        {
            int x = NumcellsSolved;
            NumcellsSolved += NakedSingles( PossibleNums, Solution );
            NumcellsSolved += HiddenSingles( PossibleNums, Solution );
            //printf("number of solved cells is %d\n", NumcellsSolved);
     
            if (x == NumcellsSolved ) break;
        }
     
        printSolution( Solution );
        //printPossibleNumbers( PossibleNums );
        printf("number of solved cells is %d\n", NumcellsSolved);
     
        return 0;
    }
     
    void RemovePossNum(int Row, int Column, int NumRemove, int PNum[][9][9] )
    {
        for ( int i = 0; i < 9; i++ )
            PNum[Row][i][NumRemove - 1] = 0;
     
        for ( int i = 0; i < 9; i++ )
            PNum[i][Column][NumRemove - 1] = 0;
     
        int x, y;
        GetRegion( Row, Column, &x, &y );
        RemoveNumRegion( x, y, NumRemove, PNum );
    }
     
    void GetRegion( int Row, int Column, int *x, int *y )
    {
        *x = Row / 3 * 3;
        *y = Column / 3 * 3;
    }
     
    void RemoveNumRegion( int x, int y, int RemoveNum, int Pnum[][9][9])
    {
        for (int i = x; i < x + 3; i++ )
            for ( int j = y; j < y + 3; j++ )
                Pnum[i][j][RemoveNum - 1] = 0;
    }
     
    void printSolution(int Solution[][9] )
    {
        for ( int i = 0; i < 9; i++ )
        {
            if ( i % 3 == 0 )
                putchar('\n');
     
            for ( int j = 0; j < 9; j++ )
            {
                if ( j % 3 == 0 )
                    putchar('\t');
     
                if ( Solution[i][j] )
                    printf("%d ", Solution[i][j]);
                else
                    printf("- ");
            }
            putchar('\n');
        }
        putchar('\n');
    }
     
    void printPossibleNumbers( int PossNum[][9][9] )
    {
        for ( int i = 0; i < 9; i++ )
            for ( int j = 0; j < 9; j++ )
            {
                printf("i = %d j = %d possibles = ", i, j);
                for ( int k = 0; k < 9; k++)
                    if ( PossNum[i][j][k] )
                        printf("%d ", PossNum[i][j][k]);
                putchar('\n');
            }
    }
     
    void SolvedCell( int Row, int Column, int Answer, int pNum[][9][9], int Solved[][9] )
    {
        Solved[Row][Column] = Answer;
        RemovePossNum( Row, Column, Answer, pNum );
     
        for ( int i = 0; i < 9; i++ )
            pNum[Row][Column][i] = 0;
    }
     
    int NakedSingles( int PossNum[][9][9], int Solved[][9] )
    {
        int CellsSolved = 0;
     
        for ( int Row = 0; Row < 9; Row++ )
            for ( int Column = 0; Column < 9; Column++ )
                CellsSolved += FindNakedSingle( Row, Column, PossNum, Solved );
    /*
        for ( int Column = 0; Column < 9; Column++ )
            for ( int Row = 0; Row < 9; Row++ )
                CellsSolved += FindNakedSingle( Row, Column, PossNum, Solved );
    
        for ( int RegionRow = 0; RegionRow < 9; RegionRow += 3 )
            for ( int RegionColumn = 0; RegionColumn < 9; RegionColumn += 3 )
                for ( int Row = RegionRow; Row < RegionRow + 3; Row++ )
                    for ( int Column = RegionColumn; Column < RegionColumn + 3; Column++ )
                        CellsSolved += FindNakedSingle( Row, Column, PossNum, Solved );
    */
        return CellsSolved;
    }
     
    int FindNakedSingle( int Row, int Column, int PossNum[][9][9], int Solved[][9] )
    {
        int CellsSolved = 0;
     
        if ( !Solved[Row][Column] )
        {
            int CountPossibleDigits = 0, tmpNum;
            for ( int Digit = 0; Digit < 9; Digit++ )
            {
                if ( PossNum[Row][Column][Digit] )
                {
                    CountPossibleDigits++;
                    tmpNum = Digit + 1;
                }
                if (CountPossibleDigits == 2 ) break;
            }
            if ( CountPossibleDigits == 1 )
            {
                SolvedCell( Row, Column, tmpNum, PossNum, Solved );
                CellsSolved++;
            }
        }
        return CellsSolved;
    }
     
    int HiddenSingles( int PossNum[][9][9], int Solved[][9] )
    {
        int CellsSolved = 0;
    
        for ( int Row = 0; Row < 9; Row++ )
        {
            int CountDigits[9] = { 0 };
     
            for ( int Column = 0; Column < 9; Column++ )
                FindHiddenSingles( Row, Column, CountDigits, PossNum, Solved );
     
            for ( int Column = 0; Column < 9; Column++ )
                CellsSolved += GetHiddenSingles( Row, Column, CountDigits, PossNum, Solved );
        }
     
        for ( int Column = 0; Column < 9; Column++ )
        {
            int CountDigits[9] = { 0 };
     
            for ( int Row = 0; Row < 9; Row++ )
                FindHiddenSingles( Row, Column, CountDigits, PossNum, Solved );
     
            for ( int Row = 0; Row < 9; Row++ )
                CellsSolved += GetHiddenSingles( Row, Column, CountDigits, PossNum, Solved );
    
        }
     
        for ( int RegionRow = 0; RegionRow < 9; RegionRow += 3 )
            for ( int RegionColumn = 0; RegionColumn < 9; RegionColumn += 3 )
            {
                int CountDigits[9] = { 0 };
                for ( int Row = RegionRow; Row < RegionRow + 3; Row++ )
                    for ( int Column = RegionColumn; Column < RegionColumn + 3; Column++ )
                        FindHiddenSingles( Row, Column, CountDigits, PossNum, Solved );
                for ( int Row = RegionRow; Row < RegionRow + 3; Row++ )
                    for ( int Column = RegionColumn; Column < RegionColumn + 3; Column++ )
                        CellsSolved += GetHiddenSingles( Row, Column, CountDigits, PossNum, Solved );
            }
     
        return CellsSolved;
    }
     
    void FindHiddenSingles( int Row, int Column, int *CountDigits, int PossNum[][9][9], int Solved[][9] )
    {
        if ( !Solved[Row][Column] )
            for ( int PossDigit = 0; PossDigit < 9; PossDigit++ )
                if ( PossNum[Row][Column][PossDigit] )
                CountDigits[ PossNum[Row][Column][PossDigit] - 1 ] += 1;
    }
     
    int GetHiddenSingles( int Row, int Column, int *CountedDigits, int PossNum[][9][9], int Solved[][9])
    {
        int CellsSolved = 0;
     
        for ( int Digit = 0; Digit < 9; Digit++ )
            if ( CountedDigits[Digit] == 1 )
                if ( PossNum[Row][Column][Digit] == Digit + 1 )
                {
                    SolvedCell( Row, Column,  Digit + 1, PossNum, Solved );
                    CellsSolved++;
                    break;
                }
     
        return CellsSolved;
    }
    A little inaccuracy saves tons of explanation. - H.H. Munro

  3. #33
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    Wow thank you.
    There are still lots of rules to factor in. like pairs of possibles or triples etc etc
    does the ifdef have to be in the same file as main or could i add a file and have lots of them.
    last question is at what point does one consider splitting a program over several files

  4. #34
    Registered User
    Join Date
    Dec 2017
    Posts
    1,633
    does the ifdef have to be in the same file as main or could i add a file and have lots of them.
    You could offload that to a separate file and #include it. However, it would be even better to use the code I posted a while back that reads them in from a file so you don't need to recompile every time. That would look like the code below. The puzzles would be in sudoku.txt and you would select the puzzle by entering its offset from the console as a command-line parameter.

    at what point does one consider splitting a program over several files
    Whenever you want. It's a packaging decision. It can be easier to deal with a single file and I don't see any reason to complicate things at this point. There's nothing wrong with having a thousand lines in a single file.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    void RemovePossNum(int, int, int, int [][9][9] );
    void GetRegion( int, int, int *, int * );
    void RemoveNumRegion( int, int, int, int [][9][9] );
    void printSolution(int [][9] );
    void printPossibleNumbers( int [][9][9] );
    void SolvedCell( int, int, int, int [][9][9], int [][9] );
    int NakedSingles( int [][9][9], int [][9] );
    int FindNakedSingle( int, int, int [][9][9], int [][9] );
    int HiddenSingles( int [][9][9], int [][9] );
    void FindHiddenSingles( int, int, int *, int [][9][9], int [][9] );
    int GetHiddenSingles( int, int, int *, int [][9][9], int [][9] );
    void ReadPuzzle(int [][9], int);
     
    int main(int argc, char **argv)
    {
        int puz = 0; // default to first puzzle in the file
        if (argc == 2) puz = atoi(argv[1]);
    
        int Solution[9][9];
        ReadPuzzle( Solution, puz );
    
        int PossibleNums[9][9][9] = {{{ 0 }}};
        for ( int i = 0; i < 9; i++ )
            for ( int j = 0; j < 9; j++ )
                if ( Solution[i][j] == 0 )
                    for ( int k = 0; k < 9; k++ )
                        PossibleNums[i][j][k] = k + 1;
     
        //printPossibleNumbers(PossibleNums);
        int NumcellsSolved = 0;
     
        for ( int i = 0; i < 9; i++ )
            for ( int j = 0; j < 9; j++ )
                if ( Solution[i][j] )
                {
                    RemovePossNum( i, j, Solution[i][j], PossibleNums );
                    NumcellsSolved++;
                }
     
        printSolution( Solution );
        printf("number of solved cells is %d\n", NumcellsSolved);
     
        while (NumcellsSolved < 81 )
        {
            int x = NumcellsSolved;
            NumcellsSolved += NakedSingles( PossibleNums, Solution );
            NumcellsSolved += HiddenSingles( PossibleNums, Solution );
            //printf("number of solved cells is %d\n", NumcellsSolved);
     
            if (x == NumcellsSolved ) break;
        }
     
        printSolution( Solution );
        //printPossibleNumbers( PossibleNums );
        printf("number of solved cells is %d\n", NumcellsSolved);
     
        return 0;
    }
     
    void ReadPuzzle(int grid[][9], int pos) {
        FILE *f = fopen("sudoku.txt", "r");
        if (!f) { perror("fopen"); exit(EXIT_FAILURE); }
        char line[256];
        for (int i = 0; fgets(line, sizeof line, f); )
            if (strncmp(line, "===", 3) == 0 && i++ == pos) break;
        if (feof(f)) {
            fprintf(stderr, "Puzzle %d does not exist\n", pos);
            exit(EXIT_FAILURE);
        }
        for (int r = 0; r < 9; ++r)
            for (int c = 0; c < 9; ++c) {
                int n = 0;
                if (fscanf(f, "%d", &n)){} // fscanf will eat the dash if present
                grid[r][c] = n; // n is 0 if no number was read
            }
        fclose(f);
    }
     
    void RemovePossNum(int Row, int Column, int NumRemove, int PNum[][9][9] )
    {
        for ( int i = 0; i < 9; i++ )
            PNum[Row][i][NumRemove - 1] = 0;
     
        for ( int i = 0; i < 9; i++ )
            PNum[i][Column][NumRemove - 1] = 0;
     
        int x, y;
        GetRegion( Row, Column, &x, &y );
        RemoveNumRegion( x, y, NumRemove, PNum );
    }
     
    void GetRegion( int Row, int Column, int *x, int *y )
    {
        *x = Row / 3 * 3;
        *y = Column / 3 * 3;
    }
     
    void RemoveNumRegion( int x, int y, int RemoveNum, int Pnum[][9][9])
    {
        for (int i = x; i < x + 3; i++ )
            for ( int j = y; j < y + 3; j++ )
                Pnum[i][j][RemoveNum - 1] = 0;
    }
     
    void printSolution(int Solution[][9] )
    {
        for ( int i = 0; i < 9; i++ )
        {
            if ( i % 3 == 0 )
                putchar('\n');
     
            for ( int j = 0; j < 9; j++ )
            {
                if ( j % 3 == 0 )
                    putchar('\t');
     
                if ( Solution[i][j] )
                    printf("%d ", Solution[i][j]);
                else
                    printf("- ");
            }
            putchar('\n');
        }
        putchar('\n');
    }
     
    void printPossibleNumbers( int PossNum[][9][9] )
    {
        for ( int i = 0; i < 9; i++ )
            for ( int j = 0; j < 9; j++ )
            {
                printf("i = %d j = %d possibles = ", i, j);
                for ( int k = 0; k < 9; k++)
                    if ( PossNum[i][j][k] )
                        printf("%d ", PossNum[i][j][k]);
                putchar('\n');
            }
    }
     
    void SolvedCell( int Row, int Column, int Answer, int pNum[][9][9], int Solved[][9] )
    {
        Solved[Row][Column] = Answer;
        RemovePossNum( Row, Column, Answer, pNum );
     
        for ( int i = 0; i < 9; i++ )
            pNum[Row][Column][i] = 0;
    }
     
    int NakedSingles( int PossNum[][9][9], int Solved[][9] )
    {
        int CellsSolved = 0;
     
        for ( int Row = 0; Row < 9; Row++ )
            for ( int Column = 0; Column < 9; Column++ )
                CellsSolved += FindNakedSingle( Row, Column, PossNum, Solved );
    /*
        for ( int Column = 0; Column < 9; Column++ )
            for ( int Row = 0; Row < 9; Row++ )
                CellsSolved += FindNakedSingle( Row, Column, PossNum, Solved );
    
        for ( int RegionRow = 0; RegionRow < 9; RegionRow += 3 )
            for ( int RegionColumn = 0; RegionColumn < 9; RegionColumn += 3 )
                for ( int Row = RegionRow; Row < RegionRow + 3; Row++ )
                    for ( int Column = RegionColumn; Column < RegionColumn + 3; Column++ )
                        CellsSolved += FindNakedSingle( Row, Column, PossNum, Solved );
    */
        return CellsSolved;
    }
     
    int FindNakedSingle( int Row, int Column, int PossNum[][9][9], int Solved[][9] )
    {
        int CellsSolved = 0;
     
        if ( !Solved[Row][Column] )
        {
            int CountPossibleDigits = 0, tmpNum;
            for ( int Digit = 0; Digit < 9; Digit++ )
            {
                if ( PossNum[Row][Column][Digit] )
                {
                    CountPossibleDigits++;
                    tmpNum = Digit + 1;
                }
                if (CountPossibleDigits == 2 ) break;
            }
            if ( CountPossibleDigits == 1 )
            {
                SolvedCell( Row, Column, tmpNum, PossNum, Solved );
                CellsSolved++;
            }
        }
        return CellsSolved;
    }
     
    int HiddenSingles( int PossNum[][9][9], int Solved[][9] )
    {
        int CellsSolved = 0;
    
        for ( int Row = 0; Row < 9; Row++ )
        {
            int CountDigits[9] = { 0 };
     
            for ( int Column = 0; Column < 9; Column++ )
                FindHiddenSingles( Row, Column, CountDigits, PossNum, Solved );
     
            for ( int Column = 0; Column < 9; Column++ )
                CellsSolved += GetHiddenSingles( Row, Column, CountDigits, PossNum, Solved );
        }
     
        for ( int Column = 0; Column < 9; Column++ )
        {
            int CountDigits[9] = { 0 };
     
            for ( int Row = 0; Row < 9; Row++ )
                FindHiddenSingles( Row, Column, CountDigits, PossNum, Solved );
     
            for ( int Row = 0; Row < 9; Row++ )
                CellsSolved += GetHiddenSingles( Row, Column, CountDigits, PossNum, Solved );
    
        }
     
        for ( int RegionRow = 0; RegionRow < 9; RegionRow += 3 )
            for ( int RegionColumn = 0; RegionColumn < 9; RegionColumn += 3 )
            {
                int CountDigits[9] = { 0 };
                for ( int Row = RegionRow; Row < RegionRow + 3; Row++ )
                    for ( int Column = RegionColumn; Column < RegionColumn + 3; Column++ )
                        FindHiddenSingles( Row, Column, CountDigits, PossNum, Solved );
                for ( int Row = RegionRow; Row < RegionRow + 3; Row++ )
                    for ( int Column = RegionColumn; Column < RegionColumn + 3; Column++ )
                        CellsSolved += GetHiddenSingles( Row, Column, CountDigits, PossNum, Solved );
            }
     
        return CellsSolved;
    }
     
    void FindHiddenSingles( int Row, int Column, int *CountDigits, int PossNum[][9][9], int Solved[][9] )
    {
        if ( !Solved[Row][Column] )
            for ( int PossDigit = 0; PossDigit < 9; PossDigit++ )
                if ( PossNum[Row][Column][PossDigit] )
                CountDigits[ PossNum[Row][Column][PossDigit] - 1 ] += 1;
    }
     
    int GetHiddenSingles( int Row, int Column, int *CountedDigits, int PossNum[][9][9], int Solved[][9])
    {
        int CellsSolved = 0;
     
        for ( int Digit = 0; Digit < 9; Digit++ )
            if ( CountedDigits[Digit] == 1 )
                if ( PossNum[Row][Column][Digit] == Digit + 1 )
                {
                    SolvedCell( Row, Column,  Digit + 1, PossNum, Solved );
                    CellsSolved++;
                    break;
                }
     
        return CellsSolved;
    }
    Input file sudoku.txt
    The numbers are just there for human readers. The three equals signs separate the puzzles. The number you put in at the command line is the offset of the puzzle to read (no matter what the written number happens to be).
    Code:
    === 0
    - - - - - - - 1 -
    4 - - - - - - - -
    - 2 - - - - - - -
    - - - - 5 - 4 - 7
    - - 8 - - - 3 - -
    - - 1 - 9 - - - -
    3 - - 4 - - 2 - -
    - 5 - 1 - - - - -
    - - - 8 - 6 - - -
    
    === 1
    - - - 5 - 6 - - -
    - - - - - - - 6 2
    7 - 4 - 1 - - - -
    9 - - - 4 3 - - 7
    - 2 - - - - - - -
    - 8 - - 9 - - 5 -
    - - - - - - - - -
    3 - - - - 8 7 - -
    - 5 - 3 - 4 - - 1
    
    === 2
    - 9 3 4 7 - - 6 -
    - 8 - - - - - - -
    - - - 6 - - - - 1
    8 - - - - - - 3 -
    - 3 4 - - 9 - - 5
    1 - - - 4 - - - -
    - - - - - 5 2 - -
    - 6 7 - 9 - - 1 -
    4 - - - - - - - -
    
    === 3
    3 - - 2 - - - - -
    - - - 1 - 7 - - -
    7 - 6 - 3 - 5 - -
    - 7 - - - 9 - 8 -
    9 - - - 2 - - - 4
    - 1 - 8 - - - 5 -
    - - 9 - 4 - 3 - 1
    - - - 7 - 2 - - -
    - - - - - 8 - - 6
    
    === 4
    - - - - - - - 1 2
    - - 8 - 3 - - - -
    - - - - - - - 4 -
    1 2 - 5 - - - - -
    - - - - - 4 7 - -
    - 6 - - - - - - -
    5 - 7 - - - 3 - -
    - - - 6 2 - - - -
    - - - 1 - - - - -
    
    === 5
    - - - - - - - 1 2
    - 5 - 4 - - - - -
    - - - - - - - 3 -
    7 - - 6 - - 4 - -
    - - 1 - - - - - -
    - - - - 8 - - - -
    9 2 - - - - 8 - -
    - - - 5 1 - 7 - -
    - - - - - 3 - - -
    
    === 6
    - - - - - - - 1 2
    3 - - - - - - 6 -
    - - - - 4 - - - -
    9 - - - - - 5 - -
    - - - - - 1 - 7 -
    - 2 - - - - - - -
    - - - 3 5 - 4 - -
    - - 1 4 - - 8 - -
    - 6 - - - - - - -
    
    === 7
    - - - - - - - 1 2
    4 - - - 9 - - - -
    - - - - - - - 5 -
    - 7 - 2 - - - - -
    6 - - - - - 4 - -
    - - - 1 - 8 - - -
    - 1 8 - - - - - -
    - - - - 3 - 7 - -
    5 - 2 - - - - - -
    
    === 8
    - - - - - - - 1 2
    5 - - - - 8 - - -
    - - - 7 - - - - -
    6 - - 1 2 - - - -
    7 - - - - - 4 5 -
    - - - - 3 - - - -
    - 3 - - - - 8 - -
    - - - 5 - - 7 - -
    - 2 - - - - - - -
    
    === 9
    - - - - - - - 1 2
    7 - - - 6 - - - -
    - - - - - - - 5 -
    - 8 - 2 - - - - -
    6 - - - - - 4 - -
    - - - 1 - 9 - - -
    - 1 9 - - - - - -
    - - - - 3 - 8 - -
    5 - 2 - - - - - -
    A little inaccuracy saves tons of explanation. - H.H. Munro

  5. #35
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    if i have the following
    Code:
    for ( int i = 0; i < 5; i++){
         if ( i == 3) break;
         some code here
    }
    the for loop will break when i = 3 rather than when i = 5 and the following code wont be executed

    if this is correct ( if it isn't free laptop to anyone that can catch it as it fly's out the window) can someone explain to me why this doesn't
    Code:
    int LockedNumbers( int PossNum[][9][9], int Solved[][9] )
    {
        int PossNumRemoved = 0;
    
        for ( int Row = 0; Row < 9; Row++ )
        {
            int CountDigits[9] = { 0 };
            for ( int Column = 0; Column < 9; Column++ )
                GetDigits( Row, Column, CountDigits, PossNum, Solved );
    
            for (int Column = 0; Column < 9; Column++ )
                for ( int DigitCount = 2; DigitCount < 4; DigitCount ++ )
                    for ( int Digit = 0; Digit < 9; Digit++ )
                        if ( CountDigits[Digit] == DigitCount )
                            if ( PossNum[Row][Column][Digit] == Digit + 1 )
                            {
                                if ( DigitCount == 2 )
                                {
                                    if ( Column % 3 == 0 )
                                    {
                                        if ( PossNum[Row][Column][Digit] != PossNum[Row][Column + 1][Digit] && PossNum[Row][Column][Digit] != PossNum[Row][Column + 2][Digit] )
                                            break;
                                    }
                                    else if ( Column % 3 == 1 )
                                    {
                                        if ( PossNum[Row][Column][Digit] != PossNum[Row][Column + 1][Digit] )
                                            break;
                                    }
                                    else // the other occurence cant be in the same region
                                            break;
                                }
                                else if ( DigitCount == 3 )
                                {
                                    if ( Column %3 != 0 )
                                        break;
                                    else if ( PossNum[Row][Column][Digit] != PossNum[Row][Column + 1][Digit] && PossNum[Row][Column][Digit] != PossNum[Row][Column + 2][Digit] )
                                        break;
                                }
    
                                int x, y;
                                GetRegion( Row, Column, &x, &y );
                                for ( int i = x; i < x + 3; i++ )
                                    if ( i != Row )
                                        for ( int j = y; j < y + 3; j++ )
                                            PossNum[i][j][Digit] = 0;
    
                                PossNumRemoved = 1;
                            }
        }
        return PossNumRemoved;
    }
    to my reckoning any of the break statements after the last for loop should break the loop and therefor all the code after shouldn't be executed but it is
    Last edited by cooper1200; 06-18-2023 at 11:17 AM.

  6. #36
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    here is the full program again as i changed some function names and edited main to include the new function
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    void RemovePossNum(int, int, int, int [][9][9] );
    void GetRegion( int, int, int *, int * );
    void RemoveNumRegion( int, int, int, int [][9][9] );
    void printSolution(int [][9] );
    void printPossibleNumbers( int [][9][9] );
    void SolvedCell( int, int, int, int [][9][9], int [][9] );
    int NakedSingles( int [][9][9], int [][9] );
    int FindNakedSingle( int, int, int [][9][9], int [][9] );
    int HiddenSingles( int [][9][9], int [][9] );
    void GetDigits( int, int, int *, int [][9][9], int [][9] );
    int GetHiddenSingles( int, int, int *, int [][9][9], int [][9] );
    int LockedNumbers( int [][9][9], int [][9] );
    
    int main()
    {
        int PossibleNums[9][9][9] = {{{ 0 }}};
    
        int Solution[9][9] = {
    
    // You can set the PUZ here or comment out this define and set
    // PUZ from the command line with, e.g., -DPUZ=5
    #define PUZ 1
    
    #if PUZ == 0
            { 0, 0, 0, 0, 0, 0, 0, 1, 0 },
            { 4, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 2, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 5, 0, 4, 0, 7 },
            { 0, 0, 8, 0, 0, 0, 3, 0, 0 },
            { 0, 0, 1, 0, 9, 0, 0, 0, 0 },
            { 3, 0, 0, 4, 0, 0, 2, 0, 0 },
            { 0, 5, 0, 1, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 8, 0, 6, 0, 0, 0 }
    #elif PUZ == 1
            { 0, 0, 0, 5, 0, 6, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 6, 2 },
            { 7, 0, 4, 0, 1, 0, 0, 0, 0 },
            { 9, 0, 0, 0, 4, 3, 0, 0, 7 },
            { 0, 2, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 8, 0, 0, 9, 0, 0, 5, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 3, 0, 0, 0, 0, 8, 7, 0, 0 },
            { 0, 5, 0, 3, 0, 4, 0, 0, 1 }
    #elif PUZ == 2
            { 0, 9, 3, 4, 7, 0, 0, 6, 0 },
            { 0, 8, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 6, 0, 0, 0, 0, 1 },
            { 8, 0, 0, 0, 0, 0, 0, 3, 0 },
            { 0, 3, 4, 0, 0, 9, 0, 0, 5 },
            { 1, 0, 0, 0, 4, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 5, 2, 0, 0 },
            { 0, 6, 7, 0, 9, 0, 0, 1, 0 },
            { 4, 0, 0, 0, 0, 0, 0, 0, 0 }
    #elif PUZ == 3
            { 3, 0, 0, 2, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 1, 0, 7, 0, 0, 0 },
            { 7, 0, 6, 0, 3, 0, 5, 0, 0 },
            { 0, 7, 0, 0, 0, 9, 0, 8, 0 },
            { 9, 0, 0, 0, 2, 0, 0, 0, 4 },
            { 0, 1, 0, 8, 0, 0, 0, 5, 0 },
            { 0, 0, 9, 0, 4, 0, 3, 0, 1 },
            { 0, 0, 0, 7, 0, 2, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 8, 0, 0, 6 }
    #elif PUZ == 4
            { 0, 0, 0, 0, 0, 0, 0, 1, 2 },
            { 0, 0, 8, 0, 3, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 4, 0 },
            { 1, 2, 0, 5, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 4, 7, 0, 0 },
            { 0, 6, 0, 0, 0, 0, 0, 0, 0 },
            { 5, 0, 7, 0, 0, 0, 3, 0, 0 },
            { 0, 0, 0, 6, 2, 0, 0, 0, 0 },
            { 0, 0, 0, 1, 0, 0, 0, 0, 0 }
    #elif PUZ == 5
            { 0, 0, 0, 0, 0, 0, 0, 1, 2 },
            { 0, 5, 0, 4, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 3, 0 },
            { 7, 0, 0, 6, 0, 0, 4, 0, 0 },
            { 0, 0, 1, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 8, 0, 0, 0, 0 },
            { 9, 2, 0, 0, 0, 0, 8, 0, 0 },
            { 0, 0, 0, 5, 1, 0, 7, 0, 0 },
            { 0, 0, 0, 0, 0, 3, 0, 0, 0 }
    #elif PUZ == 6
            { 0, 0, 0, 0, 0, 0, 0, 1, 2 },
            { 3, 0, 0, 0, 0, 0, 0, 6, 0 },
            { 0, 0, 0, 0, 4, 0, 0, 0, 0 },
            { 9, 0, 0, 0, 0, 0, 5, 0, 0 },
            { 0, 0, 0, 0, 0, 1, 0, 7, 0 },
            { 0, 2, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 3, 5, 0, 4, 0, 0 },
            { 0, 0, 1, 4, 0, 0, 8, 0, 0 },
            { 0, 6, 0, 0, 0, 0, 0, 0, 0 }
    #elif PUZ == 7
            { 0, 0, 0, 0, 0, 0, 0, 1, 2 },
            { 4, 0, 0, 0, 9, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 5, 0 },
            { 0, 7, 0, 2, 0, 0, 0, 0, 0 },
            { 6, 0, 0, 0, 0, 0, 4, 0, 0 },
            { 0, 0, 0, 1, 0, 8, 0, 0, 0 },
            { 0, 1, 8, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 3, 0, 7, 0, 0 },
            { 5, 0, 2, 0, 0, 0, 0, 0, 0 }
    #elif PUZ == 8
            { 0, 0, 0, 0, 0, 0, 0, 1, 2 },
            { 5, 0, 0, 0, 0, 8, 0, 0, 0 },
            { 0, 0, 0, 7, 0, 0, 0, 0, 0 },
            { 6, 0, 0, 1, 2, 0, 0, 0, 0 },
            { 7, 0, 0, 0, 0, 0, 4, 5, 0 },
            { 0, 0, 0, 0, 3, 0, 0, 0, 0 },
            { 0, 3, 0, 0, 0, 0, 8, 0, 0 },
            { 0, 0, 0, 5, 0, 0, 7, 0, 0 },
            { 0, 2, 0, 0, 0, 0, 0, 0, 0 }
    #elif PUZ == 9
            { 0, 0, 0, 0, 0, 0, 0, 1, 2 },
            { 7, 0, 0, 0, 6, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 5, 0 },
            { 0, 8, 0, 2, 0, 0, 0, 0, 0 },
            { 6, 0, 0, 0, 0, 0, 4, 0, 0 },
            { 0, 0, 0, 1, 0, 9, 0, 0, 0 },
            { 0, 1, 9, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 3, 0, 8, 0, 0 },
            { 5, 0, 2, 0, 0, 0, 0, 0, 0 }
    #endif
        };
    
        for ( int i = 0; i < 9; i++ )
            for ( int j = 0; j < 9; j++ )
                if ( Solution[i][j] == 0 )
                    for ( int k = 0; k < 9; k++ )
                        PossibleNums[i][j][k] = k + 1;
    
        //printPossibleNumbers(PossibleNums);
        int NumcellsSolved = 0;
    
        for ( int i = 0; i < 9; i++ )
            for ( int j = 0; j < 9; j++ )
                if ( Solution[i][j] )
                {
                    RemovePossNum( i, j, Solution[i][j], PossibleNums );
                    NumcellsSolved++;
                }
    
        printSolution( Solution );
        printf("number of solved cells is %d\n", NumcellsSolved);
    
        while (NumcellsSolved < 81 )
        {
            int x = NumcellsSolved;
            NumcellsSolved += NakedSingles( PossibleNums, Solution );
            NumcellsSolved += HiddenSingles( PossibleNums, Solution );
            //printf("number of solved cells is %d\n", NumcellsSolved);
    
            if (x == NumcellsSolved ) break;
        }
    
        printSolution( Solution );
        printPossibleNumbers( PossibleNums );
        LockedNumbers( PossibleNums, Solution );
        putchar('\n');
        printPossibleNumbers( PossibleNums );
        printf("number of solved cells is %d\n", Numcel
    //void GetThreeRegions( int, int [][9][9], int [][9] );lsSolved);
    
        return 0;
    }
    
    void RemovePossNum(int Row, int Column, int NumRemove, int PNum[][9][9] )
    {
        for ( int i = 0; i < 9; i++ )
            PNum[Row][i][NumRemove - 1] = 0;
    
        for ( int i = 0; i < 9; i++ )
            PNum[i][Column][NumRemove - 1] = 0;
    
        int x, y;
        GetRegion( Row, Column, &x, &y );
        RemoveNumRegion( x, y, NumRemove, PNum );
    }
    
    void GetRegion( int Row, int Column, int *x, int *y )
    {
        *x = Row / 3 * 3;
        *y = Column / 3 * 3;
    }
    
    void RemoveNumRegion( int x, int y, int RemoveNum, int Pnum[][9][9])
    {
        for (int i = x; i < x + 3; i++ )
            for ( int j = y; j < y + 3; j++ )
                Pnum[i][j][RemoveNum - 1] = 0;
    }
    
    void printSolution(int Solution[][9] )
    {
        for ( int i = 0; i < 9; i++ )
        {
            if ( i % 3 == 0 )
                putchar('\n');
    
            for ( int j = 0; j < 9; j++ )
            {
                if ( j % 3 == 0 )
                    putchar('\t');
    
                if ( Solution[i][j] )
                    printf("%d ", Solution[i][j]);
                else
                    printf("- ");
            }
            putchar('\n');
        }
        putchar('\n');
    }
    
    void printPossibleNumbers( int PossNum[][9][9] )
    {
        for ( int i = 0; i < 9; i++ )
            for ( int j = 0; j < 9; j++ )
            {
                printf("i = %d j = %d possibles = ", i, j);
                for ( int k = 0; k < 9; k++)
                    if ( PossNum[i][j][k] )
                        printf("%d ", PossNum[i][j][k]);
                putchar('\n');
            }
    }
    
    void SolvedCell( int Row, int Column, int Answer, int pNum[][9][9], int Solved[][9] )
    {
        Solved[Row][Column] = Answer;
        RemovePossNum( Row, Column, Answer, pNum );
    
        for ( int i = 0; i < 9; i++ )
            pNum[Row][Column][i] = 0;
    }
    
    int NakedSingles( int PossNum[][9][9], int Solved[][9] )
    {
        int CellsSolved = 0;
    
        for ( int Row = 0; Row < 9; Row++ )
            for ( int Column = 0; Column < 9; Column++ )
                CellsSolved += FindNakedSingle( Row, Column, PossNum, Solved );
    /*
        for ( int Column = 0; Column < 9; Column++ )
            for ( int Row = 0; Row < 9; Row++ )
                CellsSolved += FindNakedSingle( Row, Column, PossNum, Solved );
    
        for ( int RegionRow = 0; RegionRow < 9; RegionRow += 3 )
            for ( int RegionColumn = 0; RegionColumn < 9; RegionColumn += 3 )
                for ( int Row = RegionRow; Row < RegionRow + 3; Row++ )
                    for ( int Column = RegionColumn; Column < RegionColumn + 3; Column++ )
                        CellsSolved += FindNakedSingle( Row, Column, PossNum, Solved );
    */
        return CellsSolved;
    }
    
    int FindNakedSingle( int Row, int Column, int PossNum[][9][9], int Solved[][9] )
    {
        int CellsSolved = 0;
    
        if ( !Solved[Row][Column] )
        {
            int CountPossibleDigits = 0, tmpNum;
            for ( int Digit = 0; Digit < 9; Digit++ )
            {
                if ( PossNum[Row][Column][Digit] )
                {
                    CountPossibleDigits++;
                    tmpNum = Digit + 1;
                }
                if (CountPossibleDigits == 2 ) break;
            }
            if ( CountPossibleDigits == 1 )
            {
                SolvedCell( Row, Column, tmpNum, PossNum, Solved );
                CellsSolved++;
            }
        }
        return CellsSolved;
    }
    
    int HiddenSingles( int PossNum[][9][9], int Solved[][9] )
    {
        int CellsSolved = 0;
    
        for ( int Row = 0; Row < 9; Row++ )
        {
            int CountDigits[9] = { 0 };
    
            for ( int Column = 0; Column < 9; Column++ )
                GetDigits( Row, Column, CountDigits, PossNum, Solved );
    
            for ( int Column = 0; Column < 9; Column++ )
                CellsSolved += GetHiddenSingles( Row, Column, CountDigits, PossNum, Solved );
        }
    
        for ( int Column = 0; Column < 9; Column++ )
        {
            int CountDigits[9] = { 0 };
    
            for ( int Row = 0; Row < 9; Row++ )
                GetDigits( Row, Column, CountDigits, PossNum, Solved );
    
            for ( int Row = 0; Row < 9; Row++ )
                CellsSolved += GetHiddenSingles( Row, Column, CountDigits, PossNum, Solved );
    
        }
    
        for ( int RegionRow = 0; RegionRow < 9; RegionRow += 3 )
            for ( int RegionColumn = 0; RegionColumn < 9; RegionColumn += 3 )
            {
                int CountDigits[9] = { 0 };
                for ( int Row = RegionRow; Row < RegionRow + 3; Row++ )
                    for ( int Column = RegionColumn; Column < RegionColumn + 3; Column++ )
                        GetDigits( Row, Column, CountDigits, PossNum, Solved );
                for ( int Row = RegionRow; Row < RegionRow + 3; Row++ )
                    for ( int Column = RegionColumn; Column < RegionColumn + 3; Column++ )
                        CellsSolved += GetHiddenSingles( Row, Column, CountDigits, PossNum, Solved );
            }
    
        return CellsSolved;
    }
    
    void GetDigits( int Row, int Column, int *CountDigits, int PossNum[][9][9], int Solved[][9] )
    {
        if ( !Solved[Row][Column] )
            for ( int PossDigit = 0; PossDigit < 9; PossDigit++ )
                if ( PossNum[Row][Column][PossDigit] )
                CountDigits[ PossNum[Row][Column][PossDigit] - 1 ] += 1;
    }
    
    int GetHiddenSingles( int Row, int Column, int *CountedDigits, int PossNum[][9][9], int Solved[][9])
    {
        int CellsSolved = 0;
    
        for ( int Digit = 0; Digit < 9; Digit++ )
            if ( CountedDigits[Digit] == 1 )
                if ( PossNum[Row][Column][Digit] == Digit + 1 )
                {
                    SolvedCell( Row, Column,  Digit + 1, PossNum, Solved );
                    CellsSolved++;
                    break;
                }
    
        return CellsSolved;
    }
    
    int LockedNumbers( int PossNum[][9][9], int Solved[][9] )
    {
        int PossNumRemoved = 0;
    
        for ( int Row = 0; Row < 9; Row++ )
        {
            int CountDigits[9] = { 0 };
            for ( int Column = 0; Column < 9; Column++ )
                GetDigits( Row, Column, CountDigits, PossNum, Solved );
    
            for (int Column = 0; Column < 9; Column++ )
                for ( int DigitCount = 2; DigitCount < 4; DigitCount ++ )
                    for ( int Digit = 0; Digit < 9; Digit++ )
                        if ( CountDigits[Digit] == DigitCount )
                            if ( PossNum[Row][Column][Digit] == Digit + 1 )
                            {
                                if ( DigitCount == 2 )
                                {
                                    if ( Column % 3 == 0 )
                                    {
                                        if ( PossNum[Row][Column][Digit] != PossNum[Row][Column + 1][Digit] && PossNum[Row][Column][Digit] != PossNum[Row][Column + 2][Digit] )
                                            break;
                                    }
                                    else if ( Column % 3 == 1 )
                                    {
                                        if ( PossNum[Row][Column][Digit] != PossNum[Row][Column + 1][Digit] )
                                            break;
                                    }
                                    else // the other occurence cant be in the same region
                                            break;
                                }
                                else if ( DigitCount == 3 )
                                {
                                    if ( Column %3 != 0 )
                                        break;
                                    else if ( PossNum[Row][Column][Digit] != PossNum[Row][Column + 1][Digit] && PossNum[Row][Column][Digit] != PossNum[Row][Column + 2][Digit] )
                                        break;
                                }
    
                                int x, y;
                                GetRegion( Row, Column, &x, &y );
                                for ( int i = x; i < x + 3; i++ )
                                    if ( i != Row )
                                        for ( int j = y; j < y + 3; j++ )
                                            PossNum[i][j][Digit] = 0;
    
                                PossNumRemoved = 1;
                            }
        }
        return PossNumRemoved;
    }
    Last edited by cooper1200; 06-18-2023 at 11:28 AM.

  7. #37
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    i know this doesn't work as i get 2 naked singles that are the same on row 5

    the premises is that if i have 2 2's on the same row and in the same region then there cant be any other 2's in that region

  8. #38
    Registered User
    Join Date
    Dec 2017
    Posts
    1,633
    to my reckoning any of the break statements after the last for loop should break the loop and therefor all the code after shouldn't be executed but it is
    I don't know exactly what you're getting at, but a break will only break out of the innermost loop, so the next outer loop will keep executing and therefore the innermost loop will probably get executed again, so the code after the break could execute on another iteration of one of the outer loops. If you need to break multiple levels of loops you either need some kind of extra test (often involving a flag, or perhaps an external test of an inner-loop's index) or you need to use goto (one of the few "good" uses of that otherwise despised command).

    You have a weirdness in your posted code (line 165) :
    Code:
    ////// THIS:
        printf("number of solved cells is %d\n", Numcel
    //void GetThreeRegions( int, int [][9][9], int [][9] );lsSolved);
     
    ////// SHOULD PRESUMABLY BE THIS:
        printf("number of solved cells is %d\n", NumcellsSolved);
    I'll try looking at your program in a bit (gotta go to the hardware store to stop a leaking toilet).
    A little inaccuracy saves tons of explanation. - H.H. Munro

  9. #39
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    sorry your right it should be [code]printf("number of solved cells is %d\n", NumcellsSolved);[\code]

  10. #40
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    the for loop im trying to get out of is the digit one which is the inner most one

  11. #41
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    perhaps all this will be clearer with an example
    Code:
    1 - -     9 2 -     - - - 
    5 2 4     - 1 7     - - 9 
    - - -     - - -     2 7 1 
    
    - 5 -     - - 8     1 - 2 
    - - -     1 - 2     - - - 
    4 1 2     7 - -     - 9 - 
    
    - 6 -     - - 9     - 1 - 
    - - 1     - 3 6     9 4 5 
    - 4 -     - 7 1     - 2 6
    it can be seen that for middle right hand region only row 4 column 6 and 8 can be a 4 there fore any other element on row 4 cannot be a 4.

    like wise any other element in region 6 cant be a 4
    Last edited by cooper1200; 06-18-2023 at 01:28 PM.

  12. #42
    Registered User
    Join Date
    Dec 2017
    Posts
    1,633
    You need to loop back after the LockedNumbers call, something like the following. It's pretty close to working.
    Code:
    int main()
    {
        int PossibleNums[9][9][9] = {{{ 0 }}};
        int Solution[9][9] = {
            { 0, 0, 0, 5, 0, 6, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 6, 2 },
            { 7, 0, 4, 0, 1, 0, 0, 0, 0 },
            { 9, 0, 0, 0, 4, 3, 0, 0, 7 },
            { 0, 2, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 8, 0, 0, 9, 0, 0, 5, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 3, 0, 0, 0, 0, 8, 7, 0, 0 },
            { 0, 5, 0, 3, 0, 4, 0, 0, 1 }
        };
     
        for ( int i = 0; i < 9; i++ )
            for ( int j = 0; j < 9; j++ )
                if ( Solution[i][j] == 0 )
                    for ( int k = 0; k < 9; k++ )
                        PossibleNums[i][j][k] = k + 1;
     
        int NumcellsSolved = 0;
     
        for ( int i = 0; i < 9; i++ )
            for ( int j = 0; j < 9; j++ )
                if ( Solution[i][j] )
                {
                    RemovePossNum( i, j, Solution[i][j], PossibleNums );
                    NumcellsSolved++;
                }
     
        printSolution( Solution );
        printPossibleNumbers( PossibleNums );
        printf("\nnumber of solved cells is %d\n", NumcellsSolved);
     
        do
        {
            while (NumcellsSolved < 81 )
            {
                int x = NumcellsSolved;
                NumcellsSolved += NakedSingles( PossibleNums, Solution );
                NumcellsSolved += HiddenSingles( PossibleNums, Solution );
                if (x == NumcellsSolved ) break;
            }
     
            printSolution( Solution );
            printPossibleNumbers( PossibleNums );
            printf("\nnumber of solved cells is %d\n", NumcellsSolved);
        } 
        while ( LockedNumbers( PossibleNums, Solution ) );
     
        return 0;
    }
    You might want to try my modified printPossibleNumbers function.
    It needs a fairly wide console window, but is easier to read.
    Code:
    void printPossibleNumbers( int PossNum[][9][9] )
    {
        for ( int r = 0; r < 9; ++r ) {
            for ( int c = 0; c < 9; ++c ) {
                for ( int i = 0; i < 9; ++i )
                    if (PossNum[r][c][i]) printf("%d", i + 1);
                    else                  putchar('-');
                if (c < 8) putchar(' ');
            }
            putchar('\n');
        }
    }
    Output:
    Code:
    12-----8- --3-----9 123----89 --------- -23----8- --------- 1--4---89 --------- ---4---89
    --------- --3-----9 1-3----89 --------- --3----8- --------- 1------89 --------- ---------
    --------- --------- --------- -2-----89 --------- -2------9 ----5--89 --------- ----5--89
    --------- --------- --------- -2---6-8- --------- --------- -2---6-8- -2-----8- ---------
    ---4-6--- --------- --3--67-- -----678- -----6-8- --------- --34-6-89 --------- --34-6-89
    ---4-6--- --------- --3--67-- 12---67-- --------- 12------- -234-6--- --------- --34-6---
    12---6-8- --------- 12---6-89 12---6--9 -2--56--- 12------9 -23-56-89 --------- --3-56-89
    --------- --------- 12---6--9 12---6--9 -2--56--- --------- --------- -2------9 ----56--9
    -2---6-8- --------- -2---6-89 --------- --------- --------- -2---6-89 -2-----89 ---------
    A little inaccuracy saves tons of explanation. - H.H. Munro

  13. #43
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    this is the issue my locked numbers doesn't work with puzzle 1 just using locked numbers once after the while loop produces this
    Code:
    12-----8- --3-----9 123----89 --------- --3----8- --------- 1--4----9 --------- ---4----9
    --------- --3-----9 --3----89 --------- --3----8- --------- 1-------9 --------- ---------
    --------- --------- --------- -2-----89 --------- -2------9 ----5--89 --------- ----5--89
    --------- --------- --------- -----6-8- --------- --------- -2---6-8- -2-----8- ---------
    ---4-6--- --------- --3--67-- -----678- -----6-8- --------- --34-6--9 --------- --34-6--9
    ---4-6--- --------- --3--67-- 12---67-- --------- 12------- -----6--- --------- -----6---
    12-----8- --------- 12-----89 12---6--9 -2--56--- 12------9 -23-56-89 --------- --3-56-89
    --------- --------- 12------9 12---6--9 -2--56--- --------- --------- -2------9 -----6--9
    -2---6-8- --------- -2---6-89 --------- --------- --------- -2---6-89 -2-----89 ---------
    as you can see on row 5 i have a single six in both column 6 and 8 this cannot be as i can only have one 6 per row

  14. #44
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    i was going to do something along the lines of
    Code:
    while (NumcellsSolved < 81 )
        {
            int x = NumcellsSolved;
            NumcellsSolved += NakedSingles( PossibleNums, Solution );
            NumcellsSolved += HiddenSingles( PossibleNums, Solution );
            //printf("number of solved cells is %d\n", NumcellsSolved);
            while ( 1 )
            {
                   if ( LockedNumbers ) { x = 0; break; }
                   if ( some other functions )  { x = 0; break; }
                   break; //no x = 0 here so outer loop breaks
            }
            if (x == NumcellsSolved ) break;
        }
    all the functions inside the while (1) loop will do is eliminate possible numbers it is down to naked and hidden singles to solve the grid
    Last edited by cooper1200; 06-18-2023 at 02:42 PM.

  15. #45
    Registered User
    Join Date
    Dec 2017
    Posts
    1,633
    on row 5 i have a single six in both column 6 and 8 this cannot be as i can only have one 6 per row
    I don't see how that's a problem since they are just possible numbers, not definite values for those positions. It's just saying that the 6 must go in one of those positions (amongst three other 6's on that same row).

    The output I get when I run the program with the main I posted above is the following, which is not quite correct but pretty close. The problem seems to be that all the possible numbers have been cleared, yet the board is obviously very close to being solved.
    Code:
        - - -     5 - 6     - - - 
        - - -     - - -     - 6 2 
        7 - 4     - 1 -     - - - 
    
        9 - -     - 4 3     - - 7 
        - 2 -     - - -     - - - 
        - 8 -     - 9 -     - 5 - 
    
        - - -     - - -     - - - 
        3 - -     - - 8     7 - - 
        - 5 -     3 - 4     - - 1 
     
    12-----8- 1-3-----9 123----89 --------- -23---78- --------- 1-34---89 1-34--789 --34---89
    1---5--8- 1-3-----9 1-3-5--89 ---4--789 --3---78- ------7-9 1-345--89 --------- ---------
    --------- --3--6--9 --------- -2-----89 --------- -2------9 --3-5--89 --3----89 --3-5--89
    --------- 1----6--- 1---56--- 12---6-8- --------- --------- 12---6-8- 12-----8- ---------
    1--456--- --------- 1-3-567-- 1----678- ----5678- 1---5-7-- 1-34-6-89 1-34---89 --34-6-89
    1--4-6--- --------- 1-3--67-- 12---67-- --------- 12----7-- 1234-6--- --------- --34-6---
    12-4-6-8- 1--4-67-9 12---6789 12---67-9 -2--567-- 12--5-7-9 -23456-89 -234---89 --3456-89
    --------- 1--4-6--9 12---6--9 12---6--9 -2--56--- --------- --------- -2-4----9 ---456--9
    -2---6-8- --------- -2---6789 --------- -2---67-- --------- -2---6-89 -2-----89 ---------
     
    number of solved cells is 22
     
        - - -     5 - 6     - 7 - 
        5 - -     4 - 7     - 6 2 
        7 6 4     - 1 -     - 3 - 
    
        9 1 5     - 4 3     - - 7 
        - 2 -     - - 5     - 1 - 
        - 8 -     - 9 -     - 5 - 
    
        - 7 -     - - -     - 4 - 
        3 4 -     - - 8     7 - - 
        - 5 -     3 7 4     - - 1 
     
    12-----8- --3-----9 123----89 --------- -23----8- --------- 1--4---89 --------- ---4---89
    --------- --3-----9 1-3----89 --------- --3----8- --------- 1------89 --------- ---------
    --------- --------- --------- -2-----89 --------- -2------9 ----5--89 --------- ----5--89
    --------- --------- --------- -2---6-8- --------- --------- -2---6-8- -2-----8- ---------
    ---4-6--- --------- --3--67-- -----678- -----6-8- --------- --34-6-89 --------- --34-6-89
    ---4-6--- --------- --3--67-- 12---67-- --------- 12------- -234-6--- --------- --34-6---
    12---6-8- --------- 12---6-89 12---6--9 -2--56--- 12------9 -23-56-89 --------- --3-56-89
    --------- --------- 12---6--9 12---6--9 -2--56--- --------- --------- -2------9 ----56--9
    -2---6-8- --------- -2---6-89 --------- --------- --------- -2---6-89 -2-----89 ---------
     
    number of solved cells is 36
     
        1 3 2     5 8 6     9 7 4 
        5 9 8     4 3 7     1 6 2 
        7 6 4     2 1 -     8 3 5 
    
        9 1 5     6 4 3     2 8 7 
        6 2 7     8 - 5     4 1 3 
        4 8 3     7 9 1     6 5 - 
    
        8 7 1     - 2 9     3 4 6 
        3 4 9     1 5 8     7 2 - 
        2 5 6     3 7 4     - 9 1 
     
    --------- --------- --------- --------- --------- --------- --------- --------- ---------
    --------- --------- --------- --------- --------- --------- --------- --------- ---------
    --------- --------- --------- --------- --------- --------- --------- --------- ---------
    --------- --------- --------- --------- --------- --------- --------- --------- ---------
    --------- --------- --------- --------- --------- --------- --------- --------- ---------
    --------- --------- --------- --------- --------- --------- --------- --------- ---------
    --------- --------- --------- --------- --------- --------- --------- --------- ---------
    --------- --------- --------- --------- --------- --------- --------- --------- ---------
    --------- --------- --------- --------- --------- --------- --------- --------- ---------
     
    number of solved cells is 75
    This is pretty close to the solution that my program gets, although it looks like your program placed some numbers incorrectly:
    Code:
    1 3 2   5 8 6   4 7 9 
    5 9 8   4 3 7   1 6 2 
    7 6 4   9 1 2   5 3 8 
    
    9 1 5   2 4 3   6 8 7 
    4 2 7   8 6 5   9 1 3 
    6 8 3   7 9 1   2 5 4 
    
    8 7 1   6 2 9   3 4 5 
    3 4 9   1 5 8   7 2 6 
    2 5 6   3 7 4   8 9 1
    Last edited by john.c; 06-18-2023 at 02:56 PM.
    A little inaccuracy saves tons of explanation. - H.H. Munro

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help with multi-dimentional arrays in C
    By thebenman in forum C Programming
    Replies: 3
    Last Post: 11-01-2014, 09:13 AM
  2. 2 dimentional array
    By gameover6005 in forum C Programming
    Replies: 2
    Last Post: 04-16-2013, 09:07 PM
  3. Accessing column data in multi-dimentional arrays
    By Darkmentor in forum C Programming
    Replies: 5
    Last Post: 11-30-2012, 11:51 AM
  4. 3 Dimentional string Arrays
    By paulroseby in forum C Programming
    Replies: 3
    Last Post: 11-27-2002, 06:53 AM
  5. moving n-dimentional arrays in c++
    By kknla in forum C++ Programming
    Replies: 0
    Last Post: 02-06-2002, 05:15 PM

Tags for this Thread