Elijah Cardon posted:
Rolling the dice is what I'm not going to do. I'm going to enumerate
the outcomes.
Bitwise manipulation might be handy for minimising memory consumption. For
instance, if a dice has 6 sides, then we only need 3 bits to log each
individual roll:
000 == Rolled 1 on the dice.
001 == Rolled 2 on the dice.
010 == Rolled 3 on the dice.
011 == Rolled 4 on the dice.
100 == Rolled 5 on the dice.
101 == Rolled 6 on the dice.
For even more conservative use of memory, we can find a multiple of 6 which
is also a integral power of 2 (unfortunately though, any such number is
quite large).
This problem would be far better solved with an OO language, but if you
want to use C, then so be it. Maybe something like:
#include <stddef.h>
#include <limits.h>
#include <assert.h>
#include <stdlib.h>
typedef struct EnumInfo {
unsigned bits_per_outcom e;
size_t quant_bytes;
char unsigned *p;
} EnumInfo;
unsigned BitsNeeded(unsi gned combinations)
{
/* I'm pretty sure there's a far
better way of implementing this
function.
*/
int const assert_dummy = (assert(!!combi nations),0);
unsigned bits = 1;
--combinations;
while(combinati ons >>= 1) ++bits;
return bits;
}
EnumInfo EnumerateResult s(unsigned const throws,unsigned const sides)
{
EnumInfo info;
info.bits_per_o utcome = BitsNeeded(side s);
info.quant_byte s = info.bits_per_o utcome * (throws/CHAR_BIT +1);
/* A few bytes wasted */
/* We might want a few checks to make sure
the size_t hasn't overflowed. */
info.p = malloc(info.qua nt_bytes);
/* Write the results to memory */
return info;
}
It will be a little tricky if CHAR_BIT isn't evenly divisible by
"bits_per_outco me" (which will happen quite a lot for 6-sided die on a
system with 8-Bit bytes). The complexity could be greatly reduced however
if you used an OO language which allowed you to implement a BitHandle which
could encapsulate the nitty-gritty of the bit manipulation away from your
other code -- but still, it's achievable in C.
--
Frederick Gotham