A matrix of random numbers but each column and row add up to the same total

Viewed 78

I need to generate a matrix 7*7 and with the following rules:

  • The first and last row and column must contain a set of numbers that add up to a total of 6. And only the numbers 0, 1, 2 can be used randomly.
  • The other Columns and rows add up (each) to 12 using numbers 0 1 2 3 4 randomly.

There are additional conditions but the ultimate goal is to generate a matrix of numbers similar to this:

C/SDL Project of a pattern game

I have tried to use a code such as this one:(this is just for the first row)

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


int main()
{
    int i, j, x;
    int grille[7][7];
    int limV[7], limH[7], copy[7];


    srand ((unsigned) time (NULL));
x=0;
for(i=0; i<7; i++){
    limV[i]= 0;
    limH[i]= 0;
}

while(limH[0]!=6){
limH[0]=0;
for(i=0; i<7; i++){
  if(i==0 || i==6){
    grille[0][i] = rand()%2;
    limH[0] += grille[0][i];
    limV[i] = grille[0][i] ;
} else{
  grille[0][i] = rand()%3;
    limH[0] += grille[0][i];
    limV[i] = grille[0][i] ;
  }
}

}
return 0;
}

I am not looking for the solution to this algorithm but rather a hint or tips to be able to move forward in my project.

1 Answers

The general idea is:

  1. Fill numbers randomly
  2. Check whether the sums are correct
  3. If not, go to step 1

Or another version, probably more practical:

  1. Fill the border randomly
  2. Check whether the sums on border are correct
  3. If not, go to step 1
  4. Fill the inner 5x5 matrix randomly
  5. Check whether the sums on the inner rows and columns are correct
  6. If not, go to step 4

The probability of stumbling upon a valid matrix by chance is very low but not impractically low. To get an estimate: the probability for 5 randomly chosen numbers to make a sum of 10 is about 12%. There are 10 sums to check, so the probability is 0.12-10 (1 in a billion).

To generate a random number in the range 0...2:

rand() % 3

To generate a random number in the range 0...4:

rand() % 5

To check the sum of numbers in e.g. a column:

bool is_column_sum_correct(int grille[7][7], int column)
{
    int sum = 0;
    for (int row = 0; row < 7; ++row)
        sum += grille[row][column];
    int expected_sum = (column == 0 || column == 6) ? 6 : 12;
    return sum == expected_sum;
}

Alternatively, you can generate a few valid matrices manually, and swap columns and rows randomly to get a few more variants.

In addition to swapping, there are some other transformations which could make valid matrices. For example:

x x x x x    x x x x x
x x x x x    x x x x x
x x 0 1 x => x x 1 0 x
x x 1 3 x    x x 0 4 x
x x x x x    x x x x x

That is, take a 2x2 sub-matrix, add 1 to one of its diagonals, and subtract 1 from the other diagonal.

Repeat these transformations many times, and you will get a very different matrix.

Related