I want to generate the random number but not duplicate

I want to generate the random number. I have tried this below code. In this code random number was generating but I need every time different number between the random number range which is mention in random function.
like this
2
5
8
7
0
1.....
not a like this below
2
2
1
8
5
5.....

My code is Here. please anyone help me.

const long Interval = 1000;
unsigned long previousMillis = 0;

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  unsigned long currentMillis = millis();
  num(currentMillis, randNum());
}

void num(unsigned long currentMillis, int Num)
{
  if (currentMillis - previousMillis >= Interval)
  {
    previousMillis = currentMillis;
    Serial.println(Num);
  }
}

int randNum()
{
  int rand_Num, previousNum = 10;
  randGen:
  rand_Num = random(0,9);
  if(rand_Num == previousNum)
  {
    goto randGen;
  }
  else
  {
    previousNum = rand_Num;
    return rand_Num;
  }
}

if you can't repeat the same number twice - esp with such a short range - it's no longer really random...

do you actually want to get all the numbers between 0 and 8 but without any repeat ? or would 2,5,2 (again), 8 ... be acceptable

if you want to have all the numbers only once, in a random order, look at the FisherYates shuffle: start with an array with {0,1,2,3,4,5,6,7,8} and shuffle it then just read the data sequentially and you are sure you won't get any repeated number

I want to get all the number between 0 and 8 but my concern in if first number is 1 then again get 1. this is not work for me. if first 1 then 5 then again 1 then it is ok. it will work for me. like you said

it is acceptable. only 1,2,8,4,4(again),7(again),2 this type i mean twiceing is not accept.

I guess the risk is limited you'll get an infinite time the same random number... so you can just remember the last one you served and randomize again if you got the same one

so remember the last number and compare next with it.
In case the next the same - try again

@J-M-L @b707
Can you please look into my code. I have already done it with goto statement but i cannot get a result as per my expectation.

Can you explain in what way the code that you have published fails ?
It appears to have a test to prevent two consecutive presentations of the same random number. However, because the variable holding the last random number delivered is automatic (i.e. not global or static) its value is lost.

you need your previousNum to be static so that it's remembered across calls to the function

something like this

int getRandomNumberButNotTheSameAsLastTime(int low, int highExcluded) {
  static int lastVal = -1000;
  int result;
  do {
    result = random(low, highExcluded);
  } while (result == lastVal);
  return lastVal = result;
}

void setup() {
  Serial.begin(115200); Serial.println();
  randomSeed(analogRead(A0));
}

void loop() {
  Serial.println(getRandomNumberButNotTheSameAsLastTime(0, 9));
  delay(100);
}

Another similar solution : t1031827.ino - Wokwi Arduino and ESP32 Simulator

1 Like

What about this one?

int myRand(int low, int high) {
  static int r = random(low, high);

  int r_ = random(low, high - 1);
  if (r_ >= r) {
    r_++;
  }
  r = r_;

  return r;
}

The idea is to remove the previous random number from the choice space. This makes sure a number is not chosen twice in succession and requires no re-rolls.

2 Likes

good idea (wonder if low is less favored this way since you add a +1 bias)

EDIT

just ran this to check

seems close enough to 100,000 for each entry

2 Likes

I do not think so. Instead of working with the n original numbers, we work with (n - 1) numbers that have an equal chance to be chosen (1 / (n - 1)). The addition can be seen as a relabeling to make sure we skip the "forbidden" number.

I have to admit that statistics was not my strongest subject though.

1 Like

my wokwi code in the previous post seems to indicate indeed it is not biased. what you say makes sense to me

I test your code but it's generating twice number sometimes.
Thanks your help.

that sounds not likely ... can you show the code you used?

I test your code but it's also generating twice number sometimes.

const long Interval = 1000;
unsigned long previousMillis = 0;

void setup()
{
  Serial.begin(9600);
  randomSeed(analogRead(A0));
}

void loop()
{
  unsigned long currentMillis = millis();
  num(currentMillis, randNum());
}

void num(unsigned long currentMillis, int Num)
{
  if (currentMillis - previousMillis >= Interval)
  {
    previousMillis = currentMillis;
    Serial.println(Num);
  }
}

int randNum()
{
  static int randNum = random(0, 9);
  int randNum_ = random(0, 9 - 1);
  if (randNum_ >= randNum)
  {
    randNum_++;
  }
  randNum = randNum_;

  return randNum;
}

this is full code.
and here is output.
Second

SUre, Here is the full code.

const long Interval = 1000;
unsigned long previousMillis = 0;

void setup()
{
  Serial.begin(9600);
  randomSeed(analogRead(A0));
}

void loop()
{
  unsigned long currentMillis = millis();
  num(currentMillis, randNum());
}

void num(unsigned long currentMillis, int Num)
{
  if (currentMillis - previousMillis >= Interval)
  {
    previousMillis = currentMillis;
    Serial.println(Num);
  }
}

int randNum()
{
  int rand_Num;
  static int previousNum = -1000;
  do
  {
    rand_Num = random(0, 9);
  } while (rand_Num == previousNum);
  return previousNum = rand_Num;
}

first

that's because you generate many numbers when you do call randNum() in

num(currentMillis, randNum());

but num() only print the number once in a while.. so if you are unlucky you get the same as the previous printed one (but there were hundreds generated in between your 1s interval that never got printed out)

makes sense?

try this way where I generate the random number ONLY when I need it

but you should use @jfjlaros code as it more efficient

@J-M-L
I have already try his code. but same thing happen in their code. I have also post his code and output.

for the very same reason I explained previously... You need to generate the random number only when you are going to use it.

did you understand what I explained in post #18?

2 Likes