2

I am trying to create a sequence of 4 different numbers and randomly generated from 0 to 100 but it must have number 86, here is what I did:

#include<iostream>
#include<cstdlib>
using namespace std;

int main()
{
    srand((unsigned) time(NULL));

    // Loop to get 3 random numbers
    for(int i = 0; i < 3; i++)
    {
        int random = rand() % 101;

        // Print the random number
        cout << random << endl;
    }

    cout << 86 << endl;
}

But I don't want to put 86 at the end, are there any ways to place it at any random position in the sequence ? Thank you

  • 1
    You can do exactly as you said - place it in a random position. First, you store the four numbers to be generated in an array; then, you decide which position is `86`; then, you fill the rest and print it. – lorro Aug 14 '22 at 18:31
  • Generate 3 random numbers into an array of 4 and shuffle it. There is a stdlib function for this. – Taekahn Aug 14 '22 at 18:32
  • Also, 3 or 4 numbers? – lorro Aug 14 '22 at 18:32
  • 2
    @lorro, it's `4` but I think I only need to generate `3` because `86` is already given. –  Aug 14 '22 at 18:35

3 Answers3

3

My approach using modern C++

#include <algorithm>
#include <iostream>
#include <array>
#include <random>

namespace {

    std::default_random_engine generator(std::random_device{}());

    int random(int min, int max) {
        return std::uniform_int_distribution<int>{min, max}(generator);
    }

}

int main() {   

    std::array<int, 4> elements = {86};
    for (int i = 1; i < elements.size(); ++i) {
        elements[i] = random(0, 100);
    }

    std::shuffle(elements.begin(), elements.end(), generator);        
    for (int nbr : elements) {
        std::cout << nbr << "\n";
    }

    return 0; 
}
mwthinker
  • 59
  • 6
  • 1
    I have bad feelings about naming a function `rand()`, and worse feelings about the `default_reandom_engine`. This all culminates in the unnecessary global. Use a better engine, make it `static` inside the function, give the function a better name, make the distrubution `static` as well. – sweenish Aug 14 '22 at 19:50
  • Yes, it's reasonable concerns. I tried to avoid complicated it to much, and not deviate to much from the original code. But I think default_random_engine is good enough for the purpose here. But I will edit some code. – mwthinker Aug 14 '22 at 20:00
  • Except that you have deviated significantly. You don't use any of the constructs provided by OP. Your logic is different as well. If you are going to propose a modern C++ solution, don't go part-way with it. The "light touch" solutions have already been proposed, I see no reason to worry about deviations from the original code if your intent is to demonstrate a different (and sometimes better) way of accomplishing the task. – sweenish Aug 14 '22 at 20:04
  • Fine, but that is bit subjective I suppose. – mwthinker Aug 14 '22 at 20:10
  • It absolutely is. But your code objectively has bad practices in it to bend to your subjective take. Subjectivity in this case has its limits. – sweenish Aug 14 '22 at 20:17
  • Well I agree that naming the function rand() is not that good. Not using std::default_random_engine is definitely subjective and depending on your specific problem. Is it performance, random quality or readability you want? As a rule of thumb using a global is not that good, but limited use in small cpp file could be acceptable in order to avoid repeating code. Well I guess making the distribution static could be done but not that important. So I think you are bit harsh in your comment, but it have some merit :). – mwthinker Aug 14 '22 at 20:32
  • `int` type is hardly a good choice for an index: on 64-bit platform neither size nor signed-ness match. – Evg Aug 14 '22 at 20:37
2

You can do exactly as you said - place it in a random position. First, you store the four numbers to be generated in an array; then, you decide which position is 86; then, you fill the rest and print it.

int main()
{
    srand((unsigned) time(NULL));

    int nums[4];
    int loc86 = rand() % 4;

    for(int i = 0; i < 4; i++)
    {
        nums[i] = i != loc86 ? rand() % 101 : 86;

    }

    for(int i = 0; i < 4; i++)
    {
        // Print the random number
        cout << num[i] << endl;
    }
}

A bit offtopic, but if you really care about precision of the random number generation (and that it approaches uniform random distribution well enough), you might use pragmatic c++ random number generators as described here.

lorro
  • 10,687
  • 23
  • 36
  • Do not follow this approach if you actually want uniformly generated random numbers. Even if this were a C answer this would still be flawed. – Taekahn Aug 14 '22 at 20:41
  • @Taekahn Kindly tell me why you think so. If you mean initialization of `srand()`, I'm ok with that, but from that point, it's basically expected to be uniform random. – lorro Aug 14 '22 at 20:43
  • using modulo doesn’t provide an even distribution except in extremely specific circumstances in relation to the modulo number and the size of the random number bits. There are numerous articles about this topic as well as SO question on it. – Taekahn Aug 14 '22 at 20:44
  • @Taekahn As for the position, this is _exactly_ the case: for 16/32/64 bit RAND_MAX, it's a multiple. For the number being generated, the error rate is 1 in 100 Millions for typical 32-bit int and RAND_MAX. That's sufficient for most use-cases. Of course, you can compensate even for that, but I don't think that was the main question of OP and didn't want to divert for 1 in 100 Million precision difference when a basic question is being asked - I tried to follow their code as much as possible. – lorro Aug 14 '22 at 20:52
  • @Taekahn Anyways, added a link to the SO 'reference' question on proper c++ random number generation. – lorro Aug 14 '22 at 20:56
0

Two approaches

#include<iostream>
#include<cstdlib>
using namespace std;

int main()
{
    srand((unsigned) time(NULL));

    // Take a random position
    const int j = rand() % 4;
    
    // Loop to get 3 random numbers
    for(int i = 0; i < 4; i++)
    {
        if (i == j)
             cout << 86 << endl;
        else    
             cout << rand() % 101 << end;
    }
}
#include<iostream>
#include<algorithm>
#include<cstdlib>
using namespace std;

int main()
{
    srand((unsigned) time(NULL));

    // Fill and shuffle the array
    int r[4] = {86, rand() % 101, rand() % 101, rand() % 101};
    
    std::shuffle(std::begin(r), std::end(r));

    for(int i = 0; i < 4; i++)
         cout << r[i] << end;
}
273K
  • 29,503
  • 10
  • 41
  • 64
  • Do not follow this approach if you actually want uniformly generated random numbers. Even if the question were asking for a C answer, this would still be flawed. – Taekahn Aug 14 '22 at 20:37