Need help "shuffling" an array in arduino (permutations?)

I’m trying to make a function that returns an array full of 0’s and 1’s. What I have to do is fill the array with zero’s, and then, in chunks of 6, I have to insert a 1, 2 or 3 (randomly chosen) at random locations/indeces in each chunk (so we can assume the length of the array is divisible by 6-no problem there). For example, if I have the array A[12]={0,0,0,0,0,0,0,0,0,0,0,0}, then because I have 12 elements, I have two “6-chunks.” If it was of length 18, I’d have 3 chunks, etc. After running this function, one time I might get A={0,1,0,0,0,0,0,0,0,3,0,0}, another time A={0,0,0,0,0,1,1,0,0,0,0,0}, then A={0,0,0,3,0,0,0,0,2,0,0,0}, etc. Note that the random non-zero number only shows up once in each chunk.

I know how to make an array filled with zero’s, and I know how to generate the numbers 1, 2, and 3 randomly. Here is my code that shows this:

int randNumber;
void setup(){
  Serial.begin(9600);
  randomSeed(analogRead(0));
  generate_random_vector(120); //I want a vector of length 120
}
void loop() {
}
void generate_random_vector(int n){
  int vector[n];
  int i;
  for (i=0; i<n; i++)  {
    vector[i]=0; //filling the vector with 0's
  }
  int j;
  for (j=0; j<n; j++)  {
    Serial.println(vector[j]); //printing just to make sure it worked
  }
  randNumber = random(1, 4); //getting the random 1,2, or 3
  Serial.println(randNumber);
 
}

Here are my problems:

  1. I cant figure out a way to insert each number at a random location in chunks of six. I also looked and I don’t think Arduino has a built in permutation function.
  2. The random function doesn’t seem to be generating each number with equal probability-I’m worried that I’m using it wrong.
  3. I’m having a problem just putting it all together
  4. I have no idea how to return arrays in Arduino

Can anyone help me make this function?

A couple of things: First, use a symbolic constant to set the chunk size. That way, you could change it in one place and the code should still work. Second, since you are only using the values 1-3 in the array, you can cut its size in half by using a byte array instead of int. Finally, the memset() function is a pretty good way to initialize an array to a specific value. See if this works:

#define CHUNKSIZE 6

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

  randomSeed(analogRead(A0));  // Need to set this to a value that can vary, not 0

  generate_random_vector(120); //I want a vector of length 120
}
void loop() {
}

void generate_random_vector(int n) {
  byte vector[n];
  long randPosition;
  long randNumber;
  int i;

  memset(vector, 0, sizeof(vector));

  for (i = 0; i < n / CHUNKSIZE; i++) {
    randNumber = random(1, 4);    // Value 1 through 3
    randPosition = random(0, 6);  // Generates values 0 through 5
    vector[i * CHUNKSIZE + randPosition] = (byte) randNumber;
  }
  Serial.println("Show the array...");
  for (i = 0; i < sizeof (vector); i++) {    // Show it

    if (i % CHUNKSIZE == 0 && i != 0) {
      Serial.println();
    }
    Serial.print(vector[i]);
    Serial.print("  ");

  }
}

Econjack,
I think this is really close to what I need! Is there a way I can return a vector in arduino? I was looking this up just now and it seems I have to use pointers? Can you really just not treat arrays like a normal output variable in Arduino?

Also in case you wanted to see it for yourself, here's what gets printed to the serial board:

Show the array...
0 2 0 0 0 0
0 0 1 0 0 0
0 3 0 0 0 0
2 0 0 0 0 0
0 0 1 0 0 0
0 1 0 0 0 0
0 0 0 0 2 0
1 0 0 0 0 0
0 0 0 0 1 0
0 0 0 2 0 0
0 3 0 0 0 0
0 1 0 0 0 0
0 0 0 0 2 0
0 3 0 0 0 0
2 0 0 0 0 0
0 0 0 3 0 0
0 0 0 0 0 3
0 0 0 0 1 0
0 0 0 0 0 3
0 0 0 0 0 2

And, when I comment out the following code the vector I need gets printed:

//    if (i % CHUNKSIZE == 0 && i != 0) {
//      Serial.println();
//    }

Output after commenting that out:

Show the array...
0 2 0 0 0 0 0 0 1 0 0 0 0 3 0 0 0 0 2 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 2 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 2 0 0 0 3 0 0 0 0 0 1 0 0 0 0 0 0 0 0 2 0 0 3 0 0 0 0 2 0 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 3 0 0 0 0 1 0 0 0 0 0 0 3 0 0 0 0 0 2

What you need to remember is that an array name by itself is the memory location of the array. So, to pass the array into a function, you can modify my code to:

#define CHUNKSIZE 6

void setup() {
  byte myArray[120];           // Definition moved to here
  Serial.begin(9600);

  randomSeed(analogRead(A0));  // Need to set this to a value that can vary, not 0

  generate_random_vector(myArray, 120); //I want a vector of length 120
}
void loop() {
}

void generate_random_vector(byte *vector, int n) {   // *vector = vector[] = memory address of array

  long randPosition;
  long randNumber;
  int i;

  memset(vector, 0, n);

  for (i = 0; i < n / CHUNKSIZE; i++) {
    randNumber = random(1, 4);    // Value 1 through 3
    randPosition = random(0, 6);  // Generates values 0 through 5
    vector[i * CHUNKSIZE + randPosition] = (byte) randNumber;
  }
  Serial.println("Show the array...");
  for (i = 0; i < n; i++) {    // Show it

    if (i % CHUNKSIZE == 0 && i != 0) {
      Serial.println();
    }
    Serial.print(vector[i]);
    Serial.print("  ");

  }
}

This code works the same as before, only the array is defined in setup(). Note that you could also make the signature of the array as:

void generate_random_vector(byte vector[], int n) {

and it would still perform the same.