Most efficient way to code this RNG ?

I want to create 7 different numbers between 1 - 50 and the numbers cannot match any of the other numbers, this is what I have so far, is there an easier / cleaner way to write it or is my way fine?

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
29
30
31
32
33
34
35
//Initialise random seed

	srand (time(NULL));

        int rng = rand() % 50; 
	int rng2 = rand() % 50; 
	int rng3 = rand() % 50; 
	int rng4 = rand() % 50; 
	int rng5 = rand() % 50; 
	int rng6 = rand() % 50; 
	int rng7 = rand() % 50;

	while(rng == rng2){			
		int rng2 = rand() % 50;
	}

	while(rng3 == rng  || rng3 == rng2){
		int rng3 = rand() % 50;
	}

	while(rng4 == rng  || rng4 == rng2 || rng4 == rng3){ 
		int rng4 = rand() % 50;
	}

	while(rng5 == rng  || rng5 == rng2 || rng5 == rng3 || rng5 == rng4){ 
		int rng5 = rand() % 50;
	}
	
	while(rng6 == rng  || rng6 == rng2 || rng6 == rng3 || rng6 == rng4 || rng6 == rng5){
		int rng6 = rand() % 50;
	}

	while(rng7 == rng  || rng7 == rng2 || rng7 == rng3 || rng7 == rng4 || rng7 == rng5 || rng7 == rng6){ 
		int rng7 = rand() % 50;
	}
One way is to generate a list of whatever items you're randomizing. Then, instead of straight up rand()%50, you randomize a position in the list and remove the item at that location.
Something like this possibly?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <windows.h>
#include <ctime>
#include <vector>

int main(int argc, char** argv) {
	SetConsoleTitleA("Test");

	const unsigned short num_ints = 7;

	srand(time(0));
	std::vector<int> ints;
	for(unsigned short i=0; i<num_ints; ++i) {
		int temp = rand()%50;
		for(unsigned short j=0; j<ints.size(); ++j) {
			if(ints[j]==temp && i!=j) {
				temp = rand()%50;
			}
		}
		ints.push_back(temp);
	}

	std::cin.get();
	return 0;
}


Be careful, however. If num_ints is larger than 50, you'll end up in an infinite loop.
Here's one way to do it:

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
29
30
31
32
33
34
35
36
37
38
39
40
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <numeric>
#include <vector>

std::vector<unsigned> getUniqueRandomValues(unsigned nValues, unsigned min, unsigned max)
{
    using std::swap;

    std::vector<unsigned> result;

    // values is a vector filled with values min to max.
    std::vector<unsigned> values(max - min + 1);
    std::iota(values.begin(), values.end(), min);

    for (unsigned i = 0; i < nValues; ++i)
    {
        unsigned index = std::rand() % (values.size() - i); // pick a random unused value.

        result.push_back(values[index]);                    
        swap(values[index], values[values.size() - i - 1]); // move the used value to the end of the vector.
    }

    return result;
}

int main()
{
    std::srand(std::time(0));

    const unsigned nVals = 7;
    const unsigned minVal = 1;
    const unsigned maxVal = 50;

    std::vector<unsigned> randValues = getUniqueRandomValues(nVals, minVal, maxVal);

    for (unsigned i = 0; i < randValues.size(); ++i)
        std::cout << "#" << i+1 << ": " << randValues[i] << '\n' ;
}
Hmm I actually thought of a much better way to do it (I think) would something like this work?

1
2
3
4
5
6
7
8
	int rng[6]; //= {rand() % 50}; 

	for (int i = 0; i < 6; i++) {
		rng[i] = rand() % 50;
		if (rng[i] == rng[0] || rng[i] == rng[1] || rng[i] == rng[2] || rng[i] == rng[3] || rng[i] == rng[4] || rng[i] == rng[5] || rng[i] == rng[6]){ //Trying to make this re-randomise another number here if its equal to any of the others
			rng[i] = rand() % 50;
		}
	}


Hmm any suggestions :( ?
Hmm I actually thought of a much better way to do it (I think) would something like this work?


No. Six iterations and it's done no matter what values rng contains. It also treats all rng elements as if they were initialized, even though they were not.
I guess I will just stick with what I have then, I was just trying to make it as clean and small as possible preferably within a small loop but doesn't look possible.

Although your ways works cire (thanks for the time and effort!) its a little complex using features/functions I am not familiar with and as I am just trying to nock out the program as quick as possible for my own use, I guess I will stick with the raw basics I have learned until its completed and can spend alot of time really tidying up / optimizing.
We can trade away some flexibility for something that may be a little easier for you to understand:

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <vector>

// nValues is the number of unique values to generate.
// vals points to an array large enough to hold nValues numbers.
// min is the smallest number in the range to generate numbers for.
// max is the largest number in the range to generate numbers for.
// IMPORTANT:  max-min cannot exceed 255.
void generateUniqueRandomValues(unsigned nValues, unsigned* vals, unsigned min, unsigned max)
{
    using std::swap;
    using std::rand;

    const unsigned maxElements = 256 ;                  // some arbitrary value.
    unsigned values[maxElements];

    const unsigned valuesSize = max - min + 1;          // the number of elements of the values array which we will use.

    for (unsigned i = 0; i < valuesSize; ++i)           // fill values with numbers from min to max.
        values[i] = min + i;

    for (unsigned i = 0; i < nValues; ++i)
    {
        const unsigned valuesLeft = valuesSize - i;

        const unsigned index = rand() % valuesLeft;     // pick a random index for an unused value.
        vals[i] = values[index];                        // store the value in the user-supplied array.

        swap(values[index], values[valuesLeft-1]);      // swap the used value with the last unused value.
    }
}

int main()
{
    using namespace std;

    srand(time(0));

    const unsigned nVals = 7;
    const unsigned minVal = 1;
    const unsigned maxVal = 50;

    unsigned randValues[nVals];
    generateUniqueRandomValues(nVals, randValues, minVal, maxVal);


    for (unsigned i = 0; i < nVals; ++i)
        cout << "#" << i+1 << ": " << randValues[i] << '\n' ;
}


http://ideone.com/DhbCGp
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
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <iterator>
#include <iostream>

int main()
{
    constexpr int MIN = 1 ;
    constexpr int MAX = 50 ;
    constexpr std::size_t SZ = MAX - MIN + 1 ;
    constexpr std::size_t N = 7 ;

    std::srand( std::time(nullptr) ) ;

    // 1. create an array containing numbers 1 to 50
    int a[SZ] ;
    std::iota( std::begin(a), std::end(a), MIN ) ;

    // 2. generate a random permutation of the array
    std::random_shuffle( std::begin(a), std::end(a) ) ;

    // 3. pick the first 7 numbers
    for( std::size_t i = 0 ; i < N ; ++i ) std::cout << a[i] << ' ' ;
    std::cout << '\n' ;
}

http://ideone.com/yBrprn
Topic archived. No new replies allowed.