0

So I've been trying to store all the occurences of numbers from 1 to 9 in an array. I've succeeded for rows and columns and tried to apply the same logic for subgrids of 3x3 but to no avail.

My sudoku grid is a 2D array 9x9 (purposefully put two 9 in the same subgrid to trigger the error message).

0, 9, 0, 0, 0,,0, 0, 1, 0,
9, 0, 0, 0, 0, 0, 0, 0, 5,
8, 0, 5, 4, 0, 9, 2, 0, 7,
0, 0, 0, 3, 9, 6, 0, 0, 0,
0, 8, 0, 0, 0, 0, 0, 2, 0,
0, 0, 0, 2, 7, 8, 0, 0, 0,
3, 0, 7, 8, 0, 2, 5, 0, 9,
1, 0, 0, 0, 0, 0, 0, 0, 3,
0, 4, 0, 0, 0, 0, 0, 6, 0

Here's the code of my function:

int no_conflict_3x3(int sudoku[N][N]){
    int occurrence[N] = {0};
        for (int l=0; l<3;l++){
            for(int k = 0; k<3; k++){
                for (int i=0+3*k; i<3*k; i++){
                    for(int j=0+3*l; j<3*l; j++){
                    printf("%d", sudoku[i][j]);
                        switch(sudoku[i][j]){
                case 1:
                    occurrence[0]++;
                    break;
                case 2:
                    occurrence[1]++;
                    break;
                case 3:
                    occurrence[2]++;
                    break;
                case 4:
                    occurrence[3]++;
                    break;
                case 5:
                    occurrence[4]++;
                    break;
                case 6:
                    occurrence[5]++;
                    break;
                case 7:
                    occurrence[6]++;
                    break;
                case 8:
                    occurrence[7]++;
                    break;
                case 9:
                    occurrence[8]++;
                    break;
                default:
                    break;
                }
            }
        }
        
        for (int o = 0; o<N; o++){
                printf("o = %d : occurence=%d | ", o+1, occurrence[o]); //DEBUG
            if (occurrence[o]>1){
                printf("Not a valid sudoku grid.\n");
                return 1;}
            else occurrence[o] = 0;
            }
            printf("\n");
         
     }
     }
        
        return 0;
}

and here's the result after one iteration (for one line):

o = 1 : occurence=0 | o = 2 : occurence=0 | o = 3 : occurence=0 | o = 4 : occurence=0 | o = 5 : occurence=0 | o = 6 : occurence=0 | o = 7 : occurence=0 | o = 8 : occurence=0 | o = 9 : occurence=0 |
 

I don't know why my variable occurrence is stuck at 0. Any help please?

yk87
  • 3
  • 2
  • Your loops does nothing: `for (int i=0+3*k; i<3*k; i++){` i goes from 3*k while i <3*k ?!?!?!?! Also for j: `for(int j=0+3*l; j<3*l; j++){` – simre Apr 16 '22 at 17:39
  • What's the output of `printf("%d", sudoku[i][j]);`? – pmg Apr 16 '22 at 17:40
  • @pmg nothing at all... I've put this printf after my ```switch``` loop, is it correct? – yk87 Apr 16 '22 at 17:49
  • @yk87 Yes, but you don't enter the loop ever. See my answer. – simre Apr 16 '22 at 17:51
  • You might consider using a matrix library. That would allow you to store the cell entries in a 9x9 matrix and easily examine specific rows, columns and 3x3 sub-matrices. Alternatively, as there are only nine 3x3 groups, you could store their row and column offsets in a 3x3 array`groups`. For example, `groups[1][2] = [[[3,6],[3,7],[3,8]], [[4,6],[4,7],[4,8]], [[5,6],[5,7],[5,8]]]`. – Cary Swoveland Apr 16 '22 at 18:29
  • see [Sudoku solving in c++](https://stackoverflow.com/a/51160251/2521214) I use bitmasks for this – Spektre Apr 17 '22 at 08:59

2 Answers2

0

You have 2 ignored loops since you loop from the start to the start. Your i and j loops are like:

for (int i = 0; i < 0; ++i){...}

It does nothing.

Change

for (int i=0+3*k; i<3*k; i++){
    for(int j=0+3*l; j<3*l; j++){

to:

for (int i=3*k; i<3*(k+1); i++){
    for(int j=3*l; j<3*(l+1); j++){

Note the i < 3*k is changed to i < 3*(k + 1), similarly for j

On the other hand, you count the 'golbal occurence', but you need them in every 3x3 subgrid...

simre
  • 647
  • 3
  • 9
0
  1. We need to reset occurrences[] for every grid.

  2. We don't need to count the occurrences of a number, if it's a duplicate then we've an invalid grid (3x3)

  3. We don't need switch case, numbers themselves are good indexes into occurrences[]

#include <stdio.h>
#include <unistd.h>

#define N 9

int no_conflict_3x3 (int sudoku[N][N]) {
    // grids 3 x 3
    for (int gri = 1; gri < N; gri += 3) { // grid row id
        for (int gci = 1; gci < N; gci += 3) { // grid column id
            int occurrence[N +1] = {0}; // +1 to use  index [9]
            for (int ri = gri -1; ri <= (gri +1); ++ri) {
                for (int ci = gci -1; ci <= (gci +1); ++ci)
                    if (sudoku[ri][ci] && occurrence[sudoku[ri][ci]]) {
                        printf ("Invalid Grid, Grid Center [%d][%d].\n", gri, gci);
                        return 1;
                    } else
                        occurrence[sudoku[ri][ci]] = 1;
            }
            for (int gi = 1; gi <= N; ++gi)
                printf ("%d: occ %d | ", gi, occurrence[gi]);
            putchar ('\n');
        }
    }
    return 0;
}


int main (void) {
    int sudoku [N][N] = {
        {0, 1, 4, 0, 0, 0, 0, 1, 0},
        {9, 0, 0, 0, 0, 0, 0, 0, 5},
        {8, 0, 5, 4, 0, 9, 2, 0, 7},
        {0, 0, 0, 3, 9, 6, 0, 0, 0},
        {0, 8, 0, 0, 0, 0, 0, 2, 0},
        {0, 0, 0, 2, 7, 8, 0, 0, 0},
        {3, 0, 7, 8, 0, 2, 5, 0, 9},
        {1, 0, 0, 0, 0, 0, 0, 0, 3},
        {0, 4, 0, 0, 0, 0, 0, 6, 5}
    };
    int status = no_conflict_3x3(sudoku);

    return 0;
}
जलजनक
  • 3,072
  • 2
  • 24
  • 30