V
Virchanza
One way of counting to 999 is to use loops within loops as follows:
for (unsigned i = 0; i != 10; ++i)
for (unsigned j = 0; j != 10; ++j)
for (unsigned k = 0; k != 10; ++k)
cout << i << j << k << '\n';
I started off with the general idea of how the above code works, and
wanted to make it so that it would:
1) Work with any specified "alphabet" (for example, the decimal
alphabet is "0123456789", whereas the hexadecimal alphabet is
"0123456789abcdef")
2) Work for any length of output string (e.g. if you're counting to
999 then the length is 3).
I started off with the following recursive function:
void Combinate(char const *const pstart,
size_t const len,
char const *const alphabet,
char *p)
{
char const *const plast = (pstart + len) - 1;
for ( char const *p_alpha = alphabet; *p_alpha; ++p_alpha )
{
*p = *p_alpha;
if ( plast == p )
{
puts(pstart);
}
else
{
Combinate(pstart,len,alphabet,p+1);
}
}
}
To make it count to 999, you would call it as so:
char str[4];
Combinate(str,3,"0123456789",str);
So after I got that working, I wanted to remove the recursive-ness of
it (stack overflow and all that jazz). I removed the recursive-ness by
manually implementing a stack. Here's the code I have now:
void Combinate(char *const pstart,
size_t const len,
char const *const alphabet)
{
struct Frame {
/* Function Parameters */
char *p;
/* Local variables */
char const *p_alpha;
};
static Frame frames[16384]; /* This could be allocated
dynamically if you like */
Frame *frame_pointer = frames; /* Points to current frame! */
char const *const plast = (pstart + len) - 1;
/* >>>>>>>>>> Set up the very first frame <<<<<<<<<< */
frame_pointer->p = pstart;
/* Begin psuedo-recursive function body */
Begin_Func:
{
for ( frame_pointer->p_alpha = alphabet; *frame_pointer-
{
*frame_pointer->p = *frame_pointer->p_alpha;
if ( plast == frame_pointer->p )
{
puts(pstart);
}
else
{
/* >>>>>>>>>> Set up the next frame <<<<<<<<<< */
frame_pointer[1].p = frame_pointer->p + 1;
++frame_pointer;
goto Begin_Func;
/* Equivalent of a recursive call */
Return_Location_For_Recursive_Call: ;
}
}
if ( frames == frame_pointer )
/* OK, we're done */
return;
--frame_pointer;
goto Return_Location_For_Recursive_Call;
}
}
This function can be used to create any sort of "combinator" or
"counter", for example if you want to run through all the possible
values for a 6-letter password.
Anyway I'd just like to ask if anyone else has any other ideas on how
to write a combinator or counter like this? Is the code I have right
now optimal (I'm talking about the code that implements its own
stack) ?
for (unsigned i = 0; i != 10; ++i)
for (unsigned j = 0; j != 10; ++j)
for (unsigned k = 0; k != 10; ++k)
cout << i << j << k << '\n';
I started off with the general idea of how the above code works, and
wanted to make it so that it would:
1) Work with any specified "alphabet" (for example, the decimal
alphabet is "0123456789", whereas the hexadecimal alphabet is
"0123456789abcdef")
2) Work for any length of output string (e.g. if you're counting to
999 then the length is 3).
I started off with the following recursive function:
void Combinate(char const *const pstart,
size_t const len,
char const *const alphabet,
char *p)
{
char const *const plast = (pstart + len) - 1;
for ( char const *p_alpha = alphabet; *p_alpha; ++p_alpha )
{
*p = *p_alpha;
if ( plast == p )
{
puts(pstart);
}
else
{
Combinate(pstart,len,alphabet,p+1);
}
}
}
To make it count to 999, you would call it as so:
char str[4];
Combinate(str,3,"0123456789",str);
So after I got that working, I wanted to remove the recursive-ness of
it (stack overflow and all that jazz). I removed the recursive-ness by
manually implementing a stack. Here's the code I have now:
void Combinate(char *const pstart,
size_t const len,
char const *const alphabet)
{
struct Frame {
/* Function Parameters */
char *p;
/* Local variables */
char const *p_alpha;
};
static Frame frames[16384]; /* This could be allocated
dynamically if you like */
Frame *frame_pointer = frames; /* Points to current frame! */
char const *const plast = (pstart + len) - 1;
/* >>>>>>>>>> Set up the very first frame <<<<<<<<<< */
frame_pointer->p = pstart;
/* Begin psuedo-recursive function body */
Begin_Func:
{
for ( frame_pointer->p_alpha = alphabet; *frame_pointer-
p_alpha; ++frame_pointer->p_alpha )
{
*frame_pointer->p = *frame_pointer->p_alpha;
if ( plast == frame_pointer->p )
{
puts(pstart);
}
else
{
/* >>>>>>>>>> Set up the next frame <<<<<<<<<< */
frame_pointer[1].p = frame_pointer->p + 1;
++frame_pointer;
goto Begin_Func;
/* Equivalent of a recursive call */
Return_Location_For_Recursive_Call: ;
}
}
if ( frames == frame_pointer )
/* OK, we're done */
return;
--frame_pointer;
goto Return_Location_For_Recursive_Call;
}
}
This function can be used to create any sort of "combinator" or
"counter", for example if you want to run through all the possible
values for a 6-letter password.
Anyway I'd just like to ask if anyone else has any other ideas on how
to write a combinator or counter like this? Is the code I have right
now optimal (I'm talking about the code that implements its own
stack) ?