Here's what the book asked
The implementation of nrand in §7.4.4/135 will not work for arguments greater
than RAND_MAX. Usually, this restriction is no problem, because RAND_MAX is often the
largest possible integer anyway. Nevertheless, there are implementations under which
RAND_MAX is much smaller than the largest possible integer. For example, it is not
uncommon for RAND_MAX to be 32767 (215 -1) and the largest possible integer to be
2147483647 (231 -1). Reimplement nrand so that it works well for all values of n.
here's the original nrand() function:
int nrand(int n)
{
if (n <= 0 || n > RAND_MAX)
throw domain_error("Argument to nrand is out of range");
const int bucket_size = RAND_MAX / n;
int r;
do r = rand() / bucket_size;
while (r >= n);
return r;
}
here's the solution I created:
int nrand(int n)
{
if(n <= 0)
throw domain_error("Argument to nrand is out of range");
int r;
if(n > RAND_MAX){
typedef vector<int> veci;
typedef vector<veci> vecv;
int x = 0;
do ++x;
while(n % x != 0 && n/x > RAND_MAX);
int y = 0, z = n/x;
vecv rec(x);
for(int i = 1; i != x; ++i){
while(y != z){
rec[i -1].push_back(y);
++y;
}
z += z;
}
vecv::size_type v;
do v = rand();
while(v >= rec.size());
veci::size_type rn;
do rn = rand();
while(rn >= rec[v].size());
r = rec[v][rn];
}else{
const int bucket_size = RAND_MAX/n;
do r = rand()/bucket_size;
while(r >= n);
}
return r;
}
it should work like: (simulation with small numbers)
if RAND_MAX was 5
and
n = 18
then we'd get
x = 6
and we'd get 6 vectors with
0, 1, 2
3, 4, 5
6, 7, 8
9, 10, 11
12, 13, 14
15, 16, 17
PS: it's to get an element inside a vector so if the size is 18 I need numbers from 0 to 17 (hence why I started with 0 and not 1)
so the program should randomly select and of the numbers from 0 - 17 ... with the same chance of getting any of them.