0

I'm trying to do a programme in C, which should generate random numbers from 1 to 16, but when one number is picked it can't be picked twice, so all numbers must appear once and only once. But instead of this, some numbers are shown more than once. What's wrong?

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

int main() {

    int x[16];
    int max = 16, min = 1;

    srand(time(NULL));

    for (int i = 0; i < 16; i++) {

        x[i]= (rand() % (max-min+1)) + min;

        for (int j = 0; j < i; j++) {

            if (x[i] == x[j]) {

                while (x[i] == x[j]) {
                            
                    x[i] = (rand() % (max-min+1)) + min;
                }
            }
        }
    }

    for (int i = 0; i < 16; i++) {

        printf("\n%d", x[i]);
    }

    return 0;
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
Federico
  • 21
  • 2
  • 8
    1) Fill an array with the numbers you want 2) [shuffle the array](https://stackoverflow.com/questions/6127503/shuffle-array-in-c) 3) display (or use in some other manner) the numbers in the array – pmg Jun 10 '22 at 19:22
  • 4
    Your second `x[i] =` assignment may very well pick a number that already exists earlier in the array. There is nothing preventing that from happening – UnholySheep Jun 10 '22 at 19:23
  • So you pick 5, then find out that 5 already exists in the array, pick 6 instead, and call it a day. I wonder what could be wrong with this... – n. m. could be an AI Jun 10 '22 at 19:35
  • @Cheatah there is the same chance of rolling a number no matter how many times it has come up. – Weather Vane Jun 10 '22 at 19:53
  • @n.1.8e9-where's-my-sharem. I read it as advice. But I see now that it can also be read as a sarcastic remark. If that was the intention I apologise. I have deleted my comment. – Cheatah Jun 10 '22 at 19:58

1 Answers1

1

The logic of the inner for loop is incorrect

    for (int j = 0; j < i; j++) {

        if (x[i] == x[j]) {

            while (x[i] == x[j]) {
                        
                x[i] = (rand() % (max-min+1)) + min;
            }
        }
    }

If a duplicate number is found at the position j then after this while loop

            while (x[i] == x[j]) {
                        
                x[i] = (rand() % (max-min+1)) + min;
            }

the value in x[i] will not be equal to the value in x[j]. But this does not mean that it can not be equal for example to the value in x[j-1].

You could place in the outer for loop for example the following code snippet

for (int i = 0; i < 16; i++) {
    int j = 0;
    do
    {
        x[i]= (rand() % (max-min+1)) + min;
        j = 0;
        while ( j != i && x[i] != x[j] ) ++j;
    } while ( j != i );
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335