0

I am making Bulls and Cows assignment from Bjarne Stroustrup's "Programming Principles and Practice Using C++" book (p. 130, exercise 13) and I want program to generate four different integers in the range 0 to 9 (e.g., 1234 but not 1122)

I made a vector to store numbers and a function which generates 4 numbers and adds them to vector, but numbers might be the same and I can't return numbers to main function

#include "../..//..//std_lib_facilities.h"

vector<int> gen4Nums(vector<int> secNum)
{
    random_device rd; // obtain a random number from hardware
    mt19937 eng(rd()); // seed the generator
    uniform_int_distribution<> distr(0, 9); // define the range 

    secNum.clear();
    for (int i = 0; i < 4; i++)
    {
        secNum.push_back(distr(eng));
        cout << secNum[i];
    }
    return secNum;
}

int main()
{
        vector<int> secNum;
        gen4Nums(secNum);   
}

I expect to return 4 different random numbers to the main function

Mikhail Alexeev
  • 143
  • 1
  • 1
  • 6
  • 3
    Your function signature doesn't make much sense, it should be either `vector gen4Nums()` or `void gen4Nums(vector& secNum)` – πάντα ῥεῖ Jun 01 '19 at 20:05
  • 2
    For your use case a `std::set` seems to be the more appropriate container. Anyways you have to repeat determining the random value if you find it's already part of your result. – πάντα ῥεῖ Jun 01 '19 at 20:08
  • I mean, if you want to generate random numbers, there is [this question](https://stackoverflow.com/questions/13445688/how-to-generate-a-random-number-in-c). Not sure if it's a duplicate, only because it sounds like you're asking for debugging help, but this still might be helpful. –  Jun 01 '19 at 20:08

2 Answers2

2

You can ensure to get different random numbers in the result if you change your code like this:

#include <vector>
#include <random>
#include <algorithm>

using namespace std;

vector<int> gen4Nums()
{
    vector<int> result;
    random_device rd; // obtain a random number from hardware
    mt19937 eng(rd()); // seed the generator
    uniform_int_distribution<> distr(0, 9); // define the range 

    int i = 0;
    while(i < 4) { // loop until you have collected the sufficient number of results
        int randVal = distr(eng);
        if(std::find(std::begin(result),std::end(result),randVal) == std::end(result)) {
        // ^^^^^^^^^^^^ The above part is essential, only add random numbers to the result 
        // which aren't yet contained.
            result.push_back(randVal);
            cout << result[i];
            ++i;
        }
    }
    return result;
}

int main() {
    vector<int> secNum = gen4Nums();   
}
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
2

Seems like you're trying to generate 4 unique random integers in the range 0...9.

You can do this by generating a vector of integers containing the values 0...9. Then shuffle the vector, as you want it to be a random selection of the integers. Lastly trimming the vector to the desired size, as you only want 4 unique random integers:

#include <vector>
#include <random>
#include <algorithm>
#include <numeric>

void gen4Nums(std::vector<int>& v) {
    //Generate initial vector with values 0...9:
    v.resize(10, 0);
    std::iota(v.begin(), v.end(), 0);

    //Shuffle the vector:
    std::random_device rd;
    std::mt19937 g(rd());
    std::shuffle(v.begin(), v.end(), g);

    //Trim the vector to contain only 4 integers:
    v.resize(4);
}
Jacob
  • 3,626
  • 2
  • 20
  • 26