Random number in 2d Array without repeating

Hi, I cannot figure out what is wrong with my code below. Been trying for hours, but when I compiled, some of the numbers in the array is repeated.
I tried creating another function and pass in the value, tried to pass in boolean as well, but none of them worked. Thanks in advance.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
void Initialize(int array[][4])  
{
	for(int i=0; i<4; i++)
	{
		for(int j=0; j<4; j++)
		{
			Re:
				int num = rand()%16 +1;  // random number
				array[i][j] = num;	// put inside array
			
			
				// following is checking if there is same number(num). But it wont work
				for(int m=0; m<4; m++)
				{
					for(int n=0; n<4; n++)
					{
						if(num == array[m][n])
						{
							if(m!=i && n!=j)
							{
								goto Re;	
							}
						}		
					}
				}
		}
	}		
}	
Last edited on
oh god, is that a quadruple nested for loop with goto statement?!!? yeah, please use code tags and indentation ;D

Edit: found an online formatter/beautifier and result looks like this
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void Initialize(int array[][4])
{
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
        Re:
            int num = rand() % 16 + 1; // random number
            array[i][j] = num; // put inside array

            // following is checking if there is same number(num). But it wont work
            for (int m = 0; m < 4; m++) {
                for (int n = 0; n < 4; n++) {
                    if (num == array[m][n]) {
                        if (m != i && n != j) {
                            goto Re;
                        }
                    }
                }
            }
        }
    }
}

You want doubly nested loop at most -- anything more than that is a big red flag.

Why are you generating random numbers? Isn't a Magic Square something where all columns, rows, diagonals add up to same total? e.g.

4  9  2
3  5  7
8  1  6

(all adds up to 15)
Last edited on
The best thing to do is to load the array with the number 1 to 16 and then shuffle it (by treating it as a 1-D array).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void shuffle(int *a, int sz) {
    while (sz > 1) {
        int r = rand() % sz--;
        int t = a[r];
        a[r] = a[sz];
        a[sz] = t;
    }
}

void Initialize(int array[][4]) {
    int *a = &array[0][0];
    for (int i = 0; i < 16; i++)
        a[i] = i + 1;
    shuffle(a, 16);
}

Sorry, it is my first time posting.
no problem. Can you describe what you mean by Magic Square (as per my edited comment above)?
This magic square is one of my assignment questions. The question is to determine if a 4x4 2d array is a magic square. My code for the that part is ok ( I tried the code by cin the number one by one). But the question requires me to randomize a 4x4 2d array. I searched online, and found the swapping method as well. Just troubled by why the checking part is not working.
I tried to cout the checking process. And sometimes it does changed the num as it is repeated but sometimes it just overlooks it.
So did you try my answer yet?
so if Magic Square is how I described (you still need to confirm this and I sorta want to stab you over the internet for avoiding the question), 99% of the time your random integers won't do that.

It'd prob be more useful and fun to brute force all Magic Square solutions of NxN square by rearranging the digits from 1 to N2.

Edit: In your particular case, I suppose you could start with digits 1..16 and shuffle 1000 times or so and see if it managed to luck a solution?! So that would incorporate the randomness requirement.
Last edited on
Sorry, my bad. Instead of magic square, the topic should be: put in number randomly without repeat in 2d Array.
Yes, the shuffle is working perfectly. Just that I don't understand why my code, especially this part won' work.
1
2
3
4
5
for (int m = 0; m < 4; m++) {
                for (int n = 0; n < 4; n++) {
                    if (num == array[m][n]) {
                        if (m != i && n != j) {
                            goto Re;
Last edited on
That "part" is this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void Initialize(int array[][4])
{
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
        Re:
            int num = rand() % 16 + 1; // random number
            array[i][j] = num; // put inside array

            for (int m = 0; m < 4; m++) {
                for (int n = 0; n < 4; n++) {
                    if (num == array[m][n]) {
                        if (m != i && n != j) {
                            goto Re;
                        }
                    }
                }
            }
        }
    }
}

We can probably assume that the array is uninitialized before the function call.
Therefore, we don't know what values the array has.
Yet, already on the very first iteration the inner loops read value of every element.
Values that do not exist. The result is, by definition, undefined behaviour.


Logically you did attempt:
for each element E in array
  do
    num = random [1..16]
    E = num
  while ( any element in array other than E == num )


This would have been more defined
for each element E in array
  repeat
    num = random [1..16]
    if none of currently initialized elements == num
      E = num
      break the repeat

However, when you do reach the last element, all but one valid value have already been assigned and thus:
* there is only 1/16 chance to roll the missing value
* you have to check 15 elements for clashes

In other words this approach has to do most work when correct solution would be trivial.
Topic archived. No new replies allowed.