diff --git a/best.c b/best.c index 8a6027f..d8489f0 100644 --- a/best.c +++ b/best.c @@ -13,7 +13,10 @@ static int bestops=MAXINT; static BEST bests[1024*10]; /* TODO: should be dynamic */ static int nbests=0; +extern int displaytimer; int sigint_received=0; +int displayintermediate=0; +int displaytype=0; #define DIFF(a, b) ((a)>(b)?(a)-(b):(b)-(a)) @@ -73,14 +76,16 @@ int check_best(res, nops, node, values, ops) bests[nbests].oper=ops; bests[nbests].root=dup_node(node); bests[nbests].values=values; -# ifdef DEBUG_BEST // printf("NEW BEST! res=%d diff=%d nops=%d\n", res, diff, nops); - printf("%.5f: diff=%d nops=%d %d=", get_timer(bests[nbests].timer), - diff, nops, res); - print_node(node, TREE_TOP, 0, 4); - putchar('\n'); + if (displayintermediate) { + if (displaytimer) { + printf("%.5f secs: ", get_timer(bests[nbests].timer)); + } + printf("diff=%d nops=%d %d=", diff, nops, res); + print_node(node, TREE_TOP, 0, displaytype); + putchar('\n'); + } //printf("check_best: res=%d diff=%d nops=%d\n", res, diff, nops); -# endif nbests++; return diff; } @@ -115,12 +120,15 @@ void print_best(node, values, pops, depth) void print_bests() { - int i; - printf("BEST SOLUTION: diff=%d ops=%d\n", bestdiff, bestops); + int i=0; + printf("BEST SOLUTION: res=%d diff=%d ops=%d ", bests[i].res, bestdiff, bestops); + if (displaytimer) + printf("after %.5f secs.", get_timer(bests[i].timer)); + putchar('\n'); for (i=0; i #include -#include +#include #include #include #include #include "lceb.h" +#define TREE_CATALAN 0 +#define TREE_WEDDERBURN 1 + +static char *cmd; +static int treetype=TREE_CATALAN; +extern int displaytimer, displayintermediate, displaytype; +int displaysummary=1; + +void usage() +{ + fprintf(stderr, "usage: %s [options] target n1 n2 [...n%d]\n", cmd, MAXINPUT); +} + +void help() +{ + usage(); + fprintf(stderr, "Countdown game solver.\n"); + fprintf(stderr, " -c: Show solutions timer\n"); + fprintf(stderr, " -d TYPE: Solutions display type. TYPE can be:\n"); + fprintf(stderr, " r: RPN (default)\n"); + fprintf(stderr, " p: Polish\n"); + fprintf(stderr, " l: Lisp\n"); + fprintf(stderr, " i: Infix (full parentheses)\n"); + fprintf(stderr, " d: Suitable for dc(1) input\n"); + fprintf(stderr, " t: Tree\n"); + fprintf(stderr, " -i: Show intermediate solutions\n"); + fprintf(stderr, " -s: Do not show summary (time, nodes evaluated)\n"); + fprintf(stderr, " -t: Use less trees (Wedderburn–Etherington instead of Catalan)\n"); + fprintf(stderr, " -h: this help:\n"); +} + int main(ac, av) int ac; char **av; { unsigned target; STACK inputstack = { - "initial", - MAXINPUT, /* size */ - 0, /* last */ - NULL, /* next */ - {0} + .name="initial", + .size=MAXINPUT, + .last=0, + .next=NULL, + .stack={0} }; STACK *stack; int i, j, k, stacksize, val; int ncombs, nstacks, ntrees, nops; TREE *tree; char intarray[1024]; - int eval; char *comb; struct timespec end; + char *options="thcisd:"; + int option; +# ifdef DEBUG_MAIN + int eval; +# endif - setlocale(LC_ALL, ""); /* to use "%'d" in printf */ - if (ac < 4 || ac > 2+MAXINPUT) { - fprintf(stderr, "usage: %s target n1 n2 [...n%d]\n", *av, MAXINPUT); + cmd=*av; + + while ((option = getopt(ac, av, options)) != -1) { + //printf("opt: %c\n", option); + switch (option) { + case 'd': + switch(*optarg) { + case 'r': + displaytype=0; + break; + case 'p': + displaytype=1; + break; + case 'l': + displaytype=3; + break; + case 'i': + displaytype=4; + break; + case 't': + displaytype=2; + break; + case 'd': + displaytype=5; + break; + default: + fprintf(stderr, "unknown display type: %c\n", *optarg); + fprintf(stderr, "Try '%s -h' for help\n", cmd); + exit(1); + } + break; + case 'i': + displayintermediate=1; + break; + case 'c': + displaytimer=1; + break; + case 's': + displaysummary=0; + break; + case 't': + treetype=TREE_WEDDERBURN; + break; + case '?': + fprintf(stderr, "unknown option: %c\n", optopt); + fprintf(stderr, "%s: -%c: invalid option\n", cmd, optopt); + exit(1); + case 'h': + help(); + exit(0); + } + } + + if (ac-optind < 3 || ac-optind > MAXINPUT+1) { + usage(); exit(1); } + setlocale(LC_ALL, ""); /* to use "%'d" in printf */ start_timer(); - target=atoi(av[1]); - stacksize=2*(ac-2)-1; - nops=ac-2-1; + target=atoi(av[optind]); + stacksize=ac-optind-1; + nops=stacksize-1; gen_combinations(nops); //ncombs=ncombinations(len_ops, nops); ncombs=n_combs(); //print_combs(); - printf("target=%d\nstacksize=%d\n", target, stacksize); + printf("target=%d\nstacksize=%d ", target, stacksize); set_target(target); //printf("len_ops=%d\nnops=%d\nops_comb=%d\n", len_ops, nops, ncombs); //stack=new_stack(stacksize, "Main Stack", 1); //strcpy(inputstack.name, "initial"); - for (i=2; istack, stack->last)); */ - //gen_tree(intarray, nops, 0, 0); - gen_reduced_trees(nops+1); + if (treetype==TREE_CATALAN) { + gen_tree(intarray, nops, 0, 0); + } else { + gen_reduced_trees(nops+1); + } nstacks=n_stacks(); ntrees=n_trees(); - printf("stacks=%d\noperators combinations=%d\ntrees=%d\n", - nstacks, ncombs, ntrees); + printf("stacks :%'15d\n", nstacks); + printf("ops combinations:%'15d\n", ncombs); + printf("trees :%'15d\n", ntrees); + printf("max evaluations :%'15d\n", nstacks*ncombs*ntrees*stacksize); //for (k=0; khead, 0, stack->stack, comb, &ncalcs); -#ifdef DEBUG1 if (eval > 0) { printf("============================== %d, %d, %d\n", i, j, k); print_tree(tree, 0); @@ -105,7 +199,9 @@ int main(ac, av) printf("eval=%d - calcs=%d\n", eval, ncalcs); } -#endif +# else + eval_node(tree->head, 0, stack->stack, comb, &ncalcs); +# endif } } //opscomb=combination(ops, nops, i); @@ -121,7 +217,8 @@ int main(ac, av) printf("\n"); print_bests(); set_timer(&end); - printf("Total time elapsed: %.5f secs, nodes/leaves evaluated:%'d/%'d\n", - get_timer(end), get_totnodes(), get_totleaves()); + if (displaysummary) + printf("Total time elapsed: %.5f secs, nodes/leaves evaluated:%'d/%'d\n", + get_timer(end), get_totnodes(), get_totleaves()); exit(0); } diff --git a/lceb.h b/lceb.h index c161441..bbb060e 100644 --- a/lceb.h +++ b/lceb.h @@ -84,7 +84,7 @@ extern int n_trees(); /* stack.c */ extern void print_stack(STACK *stack, int details); extern void print_stacks(); -extern int keep_stack(STACK *stack); +//extern int keep_stack(STACK *stack); //extern STACK *new_stack(int size, char *name, int keep); extern STACK *new_stack(int size, char *name, int keep); extern int *push_stack(STACK *stack, int val); @@ -92,7 +92,7 @@ extern int *pop_stack(STACK *stack); extern STACK *dup_stack(STACK *stack, char *name); extern void swap_stack(int *elts, int i, int j); extern int permute_stack(int *array, int n); -extern int gen_stacks(STACK *stack); +extern void gen_stacks(STACK *stack); extern void mergesort_stack(int *array, int left, int right); extern STACK *nth_stack(int n); extern int n_stacks(); diff --git a/oper.c b/oper.c index 8e600ba..f8eafeb 100644 --- a/oper.c +++ b/oper.c @@ -44,6 +44,9 @@ static char *combine(ops, len, n) if (!res) { // 1st call len_ops=strlen(ops); +# ifdef DEBUG_MEM + printf("mem: allocating operators working area (%d bytes)\n", len+1); +# endif res=malloc(len * sizeof(char) + 1); } for(i=0; i #include #include +#include #include "lceb.h" -static STACK *stacks=NULL; static STACK *allstacks=NULL; static int nstacks=0; -static int totalstacks=0; -static int laststack=0; +int totalstacks=0; +int laststack=0; void print_stack(stack, details) STACK *stack; @@ -44,33 +44,31 @@ void print_stacks() } } -int keep_stack(stack) - STACK *stack; -{ - stack->next=stacks; - stacks=stack; - nstacks++; - return 1; -} - STACK *new_stack(size, name, keep) - int size; /* 0 if empty */ + int size; /* unused */ char *name; int keep; { STACK *stack; - int *pelt; int i; +# ifdef DEBUG_STACK + printf("new_stack(size=%d, name=[%s] last=%d total=%d)\n", + size, name, laststack, totalstacks); +# endif if (!allstacks) { totalstacks=ALLOCSIZE; - printf("new_stack %d: allocating %d stacks\n", laststack, totalstacks); +# ifdef DEBUG_MEM + printf("new_stack: allocating %d stacks\n", totalstacks); +# endif allstacks=malloc(totalstacks*sizeof (STACK)); } if (laststack==totalstacks) { totalstacks+=ALLOCSIZE; - printf("new_stack %d: resizing stacks array to %d\n", laststack, totalstacks); - allstacks=realloc(stacks, totalstacks*sizeof (STACK)); +# ifdef DEBUG_MEM + printf("new_stack: resizing stacks array to %d\n", totalstacks); +# endif + allstacks=realloc(allstacks, totalstacks*sizeof (STACK)); } stack=allstacks+laststack; @@ -86,8 +84,8 @@ STACK *new_stack(size, name, keep) //pelt=malloc(size*sizeof(int)); stack->size=MAXINPUT; //stack->stack=pelt; - if (keep) - keep_stack(stack); + //if (keep) + // keep_stack(stack); for (i=0; inop=0; //(pelt+i)->curop=0; @@ -107,13 +105,15 @@ int *push_stack(stack, val) int size=stack->size; int *pelt=stack->stack+stack->last; -#ifdef DEBUG_STACK - printf("push_stack(%d): last=%d size=%d\n", val, stack->last, stack->size); -#endif +# ifdef DEBUG_STACK + printf("push_stack(%d:[%s]): last=%d size=%d\n", + val, stack->name, stack->last, stack->size); +# endif if (pos >= size) { - fprintf(stderr, "stack overflow: size=%d last=%d\n", size, pos); - return NULL; + fprintf(stderr, "stack overflow: size=%d last=%d. generating core.\n", size, pos); + raise(SIGABRT); + return NULL; /* useless, we died */ } //pelt->nop=0; //pelt->curop=0; @@ -127,11 +127,12 @@ int *pop_stack(stack) STACK *stack; { int pos=stack->last+1; - int size=stack->size; int *pelt=stack->stack+stack->last; if (pos==0) { - fprintf(stderr, "stack empty: size=%d last=%d\n", size, pos); +# ifdef DEBUG_STACK + printf("pop: empty stack [%s]: size=%d last=%d\n", stack->name, stack->size, pos); +# endif return NULL; } stack->last--; @@ -143,7 +144,7 @@ STACK *dup_stack(stack, name) char *name; { STACK *new; - int *src=stack->stack, *dst; + int *dst; int size=stack->size, last=stack->last, i; new=new_stack(size, name, 0); @@ -192,24 +193,25 @@ int permute_stack(array, n) return 0; } -int gen_stacks(stack) +void gen_stacks(stack) STACK *stack; { char name[80]; int last=stack->last; int n=1; - STACK *new; int exists=1; printf("sorting stack...\n"); + printf("last=%d laststack=%d totalstacks=%d\n", last, laststack, totalstacks); //printf("before sort: "); //print_stack(stack, 0); mergesort_stack(stack->stack, 0, last-1); + printf("last=%d total=%d\n", laststack, totalstacks); //printf("after sort: "); //print_stack(stack, 0); // push initial stack //printf("++++++++++++++++ Adding main stack... "); - new=dup_stack(stack, "Main stack"); + dup_stack(stack, "Main stack"); //keep_stack(new); //print_stacks(); //print_stack(stack, 1); @@ -221,7 +223,7 @@ int gen_stacks(stack) //print_stack(stack, 0); if (exists) { //printf("++++++++++++++++ Adding stack... "); - new=dup_stack(stack, name); + dup_stack(stack, name); // print_stack(new, 0); //keep_stack(new); }