Re: Ideas for writing a "Combinator"
"robertwessel2@yahoo.com" <robertwessel2@yahoo.com> writes:
On Apr 19, 5:12?pm, Virchanza <virt...@lavabit.com> wrote:
(...)
void Combinate(char *const pstart,
size_t const len,
(...)
Allocating 16384 entries for frames is a bit absurd.
Leaving every other line of the source code empty and then
full-quoting this is as absurd.
I just wrote this C code to count in any base with
user-defined digits. The digits can have any length, so we
are not limited to as many digits as there are characters of
the execution character set (but currently there can be at
most about INT_MAX digits), and everything is allocated at
run time, so we are not limited to 16384 entries per frame.
But there still is recursion, which limits the number of
frame entries to a value related to the stack size.
#include <stdio.h>
#include <stdlib.h>
#define STRING char *
int N = 12; /* how many lines to write. Just used in main,
so one could use any other means to terminate the main loop.
For example, one can replace "for( int i = 0; i < N; ++i )"
below by "while( 1 )" in order to count forever. */
STRING names[]={ "0", "1", "2" }; /* the digits to be used.
Can be arbitrary strings.
Three digits specify a ternary number system. */
/* the output for the above data is:
0
1
2
10
11
12
20
21
22
100
101
102
*/
/* array */
int * n; int length;
int has_next;
int base;
STRING * arg;
STRING * result;
static int inc( int const p )
{ int result;
if( p < length )
{ if( n[ p ] < base - 1 ){ ++n[ p ]; result = 1; }
else { n[ p ]= 0; result = inc( p + 1 ); }}
else result = 0;
return result; }
static int increment()
{ return inc( 0 ); }
static STRING * dress()
{ for( int i = 0; i < length; ++i )
result[ i ]= arg[ n[ i ]];
return result; }
void array( int const l, void * a, int al )
{ length = l;
arg = a;
n = malloc( length * sizeof( int )); if( !n )abort();
result = malloc( length * sizeof( char * )); if( !result )abort();
for( int i = 0; i < length - 1; ++i )n[ i ]= 0;
n[ length - 1 ]= length > 1;
base = al;
has_next = length > 0 && base > 0; }
int hasnext(){ return has_next; }
STRING * next()
{ void * result = dress();
has_next = increment();
return result; }
/* counter */
int len;
int s = sizeof( names )/sizeof( STRING );
void counter()
{ len = 1;
array( len, names, s ); }
STRING * count()
{ if( !hasnext() )
{ free( n ); free( result ); ++len; array( len, names, s ); }
return next(); }
/* main */
int main(int argc, char *argv[])
{ counter();
for( int i = 0; i < N; ++i )
{ STRING * value = count();
for( int j = len - 1; j >= 0; --j )
printf( "%s", value[ j ]);
printf( "\n" ); }
free( result );
free( n ); }
Exercise: Convert the code sections ?array? and ?counter?
into two C++ classes, so as to structure the code in a more
object-oriented manner, and rewrite everything into
idiomatic C++ style, using ?new?, ?::std::string? and so.