0

How can I make a random 4x4 array<array<int,4>,4>? Each element of this 2D array should be unique number from the interval from 0 to 15, inclusive.

Example:

6   7  5  4
10 11  12 15
1   3  2  8
9  14  0  13
8
  • 3
    Homework? If yes, tag please. Commented Jun 19, 2012 at 21:12
  • @Ruben No, this is not homework. This is a new part of process that I want to put my project. Commented Jun 19, 2012 at 23:18
  • The question is closed now, but since you've finally decided that this isn't homework (not sure if I believe you), here's how I would do it: ideone.com/48OPe Commented Jun 20, 2012 at 3:02
  • 1
    @ildjarn why wouldn't you re-open now that you know that you decided on wrong assumption? How is a question: How can I make a random 4x4 array<array<int,4>,4> not constructive? Commented Jun 20, 2012 at 13:51
  • @rubberboots : What do you mean "I decided"? Do you see my name in the list of people who voted to close? Troll elsewhere. Commented Jun 20, 2012 at 16:55

2 Answers 2

5

Here are some steps that you could follow:

  1. define your array: std::array<std::array<int, 4>, 4> myArray;
  2. prepare an temporary std::vector of size 16, that contains values from 0 to 15.
  3. reorder elements of this vector randomly, I recommend you to have a look at std::random_shuffle
  4. use this vector to initialize your array
Sign up to request clarification or add additional context in comments.

5 Comments

The original question doesn't actually require uniqueness. (It probably meant to, but the wording is weird.)
@aschepler: The uniqueness requirement is clear from example that was given by OP when he has edited his question thus I've edited my answer as well.
how do you initialize the array from the vector ?
@georgemano: Just assign values from the vector one by one to elements of your array: for (int i = 0, k = 0; i < 4; ++i) for (int j = 0; j < 4; ++j) myArray[i][j] = values[k++];
vector<int> myvector; for (int i=0; i<15; ++i) myvector.push_back(i); random_shuffle ( myvector.begin(), myvector.end() ); for (int i=0; i<15; ++i) cout << " " << myvector[i]; Why does this always print the same sequence of numbers? Why doesnt it randomise every time i run it ?
1

Not a bad question. This would be my pick:

How to generate subsequent array values, mix them and initialize 2D arrays with them?

I extended my answer to include another (simple) solution to the problem using std::vector only, and std::vector + std::array (as asked by the O.P.).

  #include <vector>
  #include <array>
  #include <algorithm>
  using namespace std;

  // ...
  const int N = 4;  // we want to have 4x4 arrays for now
  // ...

  // C++ was tremendously simplified over the years in order to 
  // get a much more complicated language. This is what you can do ...

  // ...
  // First, generate a std::vector of shuffled numbers [0..15] over 16 elements
  vector<int> v;
  for(int i=0; i<N*N; i++) v.push_back(v.size()); // initialize w/index
  random_shuffle (v.begin(), v.end());            // shuffle element values

  // (Variant 1) std::array (C++11), row-wise copy of the vector data
  //  + will only work with newer (C++11 enabled) compiler versions
  array<array<int,N>,N> amat;  // there's no assign() member, so we have
  for(int i=0; i<N; i++)       // to copy each row through external template
     copy( v.begin()+i*N, v.begin()+(i+1)*N, amat[i].begin() );
  // done
  // ...

In the for loop, we only do 4 iterations but have a total of 4x4 elements. Because each of the 4 matrix rows is 4 elements wide, we have to find a way how we take the correct 4 elements for each matrix row from our shuffeld 16-element 1D vector v: v.begin()+i*N ... v.begin()+(i+1)*N. If i is 0 (first iteration), we copy the four elements from v[0 * N] ... v[0+1 * N], this means v[0] .. v[4].

This is a sequence where the last element v[4] is not included in the copy. This is also somehow an idiomatic pattern in C/C++ which is comparable to: for(i=START; i < END; i++) .... The END element is therefore beyond the range, not included.

In the second iteration (i = 1), we have v[1 * N] ... v[1+1 * N], which is v[4] ... v[8]. You see the pattern?

  // ...
  // (Variant 2) std::vector (STL), row-wise copy of the vector data
  //  + should work with almost every c++ compiler
  vector<vector<int>> vmat(N);
  for(int i=0; i<N; i++) 
     vmat[i].assign( v.begin()+i*N,  v.begin()+(i+1)*N );
  // done
  // ...
  // TODO: now try to print all elements line 4x4 matrix

Why is the shuffled order always the same? The C library uses a random number implementation that starts from the same seed number generating always the same sequence (which might be important for debugging). In order to get different shuffling, you'd have to re-initialize the random number generator at the program start once.

 ...
 srand((unsigned)time(NULL))
 ...

For this, you need the C-library time-header (for time()) and most probably stdlib-header (for srand()):

 ...
 #include <ctime>
 #include <cstdlib>
 ...

I deliberately tried to provide very simple solutions only. Therefore, no generators or C++11 lambdas seemed appropriate for this purpose.

Regards

rbo

7 Comments

See here.
@sbi - oops, I wasn't aware of that. What now? Could you modify the OP's question somehow in order to make the answers valid (if the are at all).
@sbi - nope, this is definitely not a homework question. This is a interesting problem -that many programmers encounter sometimes.
@rubberboots : I didn't downvote your answer, but this definitely appears to be a homework question...
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.