C language - How to make a sudoku like board with 9 pieces of 3x3 matrix, without any input

92 Views Asked by At

How to make Sudoku board like number generator with some catch:
- In one line of row/column there are random non-repeating numbers from 1 to 9 ?

Here are my source code

#include <stdio.h>
#include <stdlib.h>

int main()
{
  int matrix [9][3][3];

  srand(time(NULL));

  mengisi_Matrix(matrix);

  tampilkan_Matrix(matrix);

  return 0;
}

void mengisi_Matrix(int matrix [9][3][3])
{
  for (int i = 1; i < 10; i++)
  {
    for (int j = 1; j < 4; j++)
    {
      for (int k = 1; k < 4; k++)
      {
        matrix[i][j][k] = (rand() % 9) + 1;
      }
    }
  }
}

void tampilkan_Matrix(int matrix [9][3][3])
{
  for (int i = 1; i < 10; i++)
  {
    printf("| ");

    for (int j = 1; j < 4; j++)
    {
      for (int k = 1; k < 4; k++) 
      {
        printf("%d ", matrix[i][j][k]);
      }

      printf("| ");

    }

    printf("\n");
    
    if (i % 3 == 0)
    {
      printf("- - - - + - - - + - - - - \n");
    }
  }
} 

I tried to fill up in one line via one by one random numbers using srand().

But before input it into let say array[1][1][2], I want to compare the random generated number with same all of the array in same row/column, if there is already exist the number it will generate new random number and so on and so on until all of array[9][3][3] filled up.

I have tried bunch of my own logic and tried to ask AI but no still no solution, there is always unwanted and non-logic (for me) problems/errors/warning such as implicit declaration or conflicting types. Hope you guys who are more pro and expert than me can help me to figure this out.

1

There are 1 best solutions below

1
ikegami On

You can use a Fisher–Yates shuffle.

void swap_ints( int *i, int *j ) {
   int tmp = *i;
   *i = *j;
   *j = tmp;
}

// An `int` in [0,n).
int rand_int( n ) {
   return rand() % n;
}

void shuffle( size_t n, int *a ) {
   while ( n-- )
      swap_ints( &a[ n ], &a[ rand_int( n + 1 ) ] );
}

For example,

#define NUM_ELEMENTS( a ) ( sizeof( a ) / sizeof( *a ) )

int row[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

shuffle( NUM_ELEMENTS( row ), row );
|-----------------------------------|  Unused

     Pick one of the unused and move to end.
              +-------------------+
              |                   |
+---+---+---+-|-+---+---+---+---+-v-+
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
+---+---+---+-^-+---+---+---+---+-|-+
              |                   |
              +-------------------+
         Bump old value into unused pool.

|-------------------------------|  Unused

+---+-|-+---+---+---+---+---+-v-+ ---+
| 1 | 2 | 3 | 9 | 5 | 6 | 7 | 8 |  4 |
+---+-^-+---+---+---+---+---+-|-+ ---+

|---------------------------|  Unused

+---+---+---+---+---+---+-|-+ ---+---+  Not moving
| 1 | 8 | 3 | 9 | 5 | 6 | 7 |  2 | 4 |  is possible.
+---+---+---+---+---+---+-^-+ ---+---+  That's fine.

+---+---+---+-|-+---+-v-+ ---+---+---+  Same for
| 1 | 8 | 3 | 6 | 5 | 9 |  7 | 2 | 4 |  moving more
+---+---+---+-^-+---+-|-+ ---+---+---+  than once.

...

+---+---+---+---+---+---+---+---+---+
| 6 | 8 | 1 | 5 | 3 | 9 | 7 | 2 | 4 |
+---+---+---+---+---+---+---+---+---+

Whenever you pick a number for a position, every available option has an equal change of being picked. This means this is a fair algorithm (given a fair implementation of rand_int).