Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fill array with specific number of 1's and 0's in random locations?

I have an array with 8 spots to fill and 4 ones and 4 zeros to fill it with, but want the locations to be random. I am a bit stumped on how to do this without it being to redundant. Is there a simple way to do this or will I have to fill the array with either a 1 or a zero randomly then go through and check to see if it has the right number of both after the fact? My current code is along the lines of

void setup() {
  int one = 0;
  randomSeed(analogRead(A0));
  for (int i=0; i<8; i++){
    array[i] = random(0, 2);
    if (array[i] == 1){
      one++;
    }
    if(one >4){
      array[i] = 0;
      one--;
    }
  }
}

This mostly works but has the some obvious drawbacks so any pointers on a better way to do this would be appreciated.

like image 420
Christian Remwood Wikitiki33 Avatar asked Oct 23 '17 18:10

Christian Remwood Wikitiki33


Video Answer


2 Answers

Update: This answer has changed slightly from the original

For an Arduino where resources are tight, this code would suffice, no need to link in extra libraries:

int a[8] = { 0,0,0,0,1,1,1,1 };


void setup() {

  randomSeed(analogRead(A0));

  for (int n=7;n>0;n--) {
    int r = random(n+1);
    int t = a[n];
    a[n] = a[r];
    a[r] = t;
  }

}

This is exactly how the std::shuffle function is implemented, limited only by the effectiveness of the implementation of the builtin Arduino random() function

like image 71
Octopus Avatar answered Sep 20 '22 18:09

Octopus


If you need to generate m random ones in an array of zeroes, you can simply iterate through the entire array and set the current element to 1 with the following probability P

           number of 1's that remains to be set
P = ----------------------------------------------------
    number of array elements that remains to be iterated

In your case you need to set 4 random 1's in an array of 8 elements

const unsigned N = 8, M = 4;
int array[N];

for (unsigned i = 0, m = M; i < N; ++i)
  if (rand() % (N - i) < m)
  {
    array[i] = 1;
    --m;
  }
  else
    array[i] = 0;

This generates the random array in one pass - no need to post-shuffle anything.

P.S. In order to make the decision with the above probability P I used the oft-criticized rand() % (N - i) < m method. This is besides the point, of course. You can use any other method of your choice.

like image 30
AnT Avatar answered Sep 16 '22 18:09

AnT