diff --git a/Makefile b/Makefile index 20710a8..c6f3ff2 100644 --- a/Makefile +++ b/Makefile @@ -13,23 +13,27 @@ CFLAGS:=$(CFLAGS) -O3 #CFLAGS:=$(CFLAGS) -pg ##################################### DEBUG flags: -CFLAGS:=$(CFLAGS) -DDEBUG # general -#CFLAGS:=$(CFLAGS) -DDEBUG1 # temp -#CFLAGS:=$(CFLAGS) -DDEBUG_MAIN # main +CFLAGS:=$(CFLAGS) -DDEBUG # general (signal handler, etc...) +CFLAGS:=$(CFLAGS) -DDEBUG_MAIN # general information in main +#CFLAGS:=$(CFLAGS) -DDEBUG_MAINSLEEP # sleep 1 sec within main loop (SIGINTR test) +#CFLAGS:=$(CFLAGS) -DDEBUG_MAINLOOP # main loop (do not use this!) #CFLAGS:=$(CFLAGS) -DDEBUG_TIMER # timer +#CFLAGS:=$(CFLAGS) -DDEBUG_SIGNAL # signal #CFLAGS:=$(CFLAGS) -DDEBUG_BEST # best control #CFLAGS:=$(CFLAGS) -DDEBUG_TREE # tree #CFLAGS:=$(CFLAGS) -DDEBUG_OPER # oper #CFLAGS:=$(CFLAGS) -DDEBUG_STACK # stack +#CFLAGS:=$(CFLAGS) -DDEBUG_STACK2 # stack - more details #CFLAGS:=$(CFLAGS) -DDEBUG_EVAL # eval #CFLAGS:=$(CFLAGS) -DDEBUG_EVAL2 # eval 2 -CFLAGS:=$(CFLAGS) -DDEBUG_MEM # malloc +#CFLAGS:=$(CFLAGS) -DDEBUG_EVAL3 # eval 3 +CFLAGS:=$(CFLAGS) -DDEBUG_MEM # malloc TIME := \time -f "\ttime: %E real, %U user, %S sys\n\tcontext-switch:\t%c+%w, page-faults: %F+%R\n" export PATH := .:$(PATH) TARGETS=lceb tree oper timer -OBJS=lceb.o tree.o oper.o stack.o eval.o best.o timer.o stack.o +OBJS=lceb.o tree.o oper.o stack.o eval.o best.o timer.o stack.o signal.o INCLUDES=lceb.h DEPS=$(INCLUDES) Makefile diff --git a/best.c b/best.c index c8a82c7..b7e0b49 100644 --- a/best.c +++ b/best.c @@ -7,35 +7,24 @@ #include "lceb.h" static int target=0; -//static int best=MAXINT; static int bestdiff=MAXINT; 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)) -void stopall() -{ - printf("SIGINT RECEIVED: aborting eval\n"); - sigint_received=1; -} - -int stopped() -{ - return sigint_received; -} - void set_target(n) int n; { target=n; - signal(SIGINT, stopall); +# ifdef DEBUG + printf("target assigned (%d).\n", target); +# endif } int check_best(res, nops, node, values, ops) @@ -81,7 +70,6 @@ int check_best(res, nops, node, values, ops) } # endif } - //} if (found) { set_timer(&(bests[nbests].timer)); bests[nbests].res=res; @@ -90,7 +78,6 @@ int check_best(res, nops, node, values, ops) bests[nbests].oper=ops; bests[nbests].root=dup_node(node); bests[nbests].values=values; - // printf("NEW BEST! res=%d diff=%d nops=%d\n", res, diff, nops); if (displayintermediate) { if (displaytimer) { printf("%.5f secs: ", get_timer(bests[nbests].timer)); @@ -99,7 +86,6 @@ int check_best(res, nops, node, values, ops) print_node(node, TREE_TOP, 0, displaytype); putchar('\n'); } - //printf("check_best: res=%d diff=%d nops=%d\n", res, diff, nops); nbests++; return diff; } @@ -136,12 +122,14 @@ void print_bests() { 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)); + //if (displaytimer) + printf("found after %.5f secs.", get_timer(bests[i].timer)); putchar('\n'); for (i=0; ileft, depth+1, pvals, ops, &lcalcs); - //printf("val1=%d ", val1); if (val1 <= 0) - return -1; + return val1; val2=eval_node(node->right, depth+1, pvals, ops, &rcalcs); - //printf("val2=%d\n", val2); if (val2 <= 0) - return -1; + return val2; switch (op) { case Add: res=val1+val2; @@ -103,14 +101,25 @@ int eval_node(node, depth, pvals, pops, ncalcs) *ncalcs=lcalcs+rcalcs+1; } if (res > 0) { - if (!check_best(res, *ncalcs, node, val_zero, ops_zero)) - res=-1; + diff=check_best(res, *ncalcs, node, val_zero, ops_zero); + //printf("eval=%d firstonly=%d\n", eval, firstonly); + if (diff == 0) { /* exact result, we stop here */ +# ifdef DEBUG_EVAL3 + printf("EXACT eval=%d\n", diff); +# endif + if (firstonly) { + print_results(); + exit(0); + } + res=0; + } } if (sigint_received) { print_bests(); exit(1); } -# ifdef DEBUG1 + +# ifdef DEBUG_EVAL for (i=0; i<=depth; ++i) printf(" "); printf("res=%d\n", res); diff --git a/lceb.c b/lceb.c index f2ddf06..fe3ae38 100644 --- a/lceb.c +++ b/lceb.c @@ -20,9 +20,19 @@ static char *cmd; static int treetype=TREE_CATALAN; -extern int displaytimer, displayintermediate, displaytype; +extern int displaytimer, displayintermediate, displaytype, firstonly; int displaysummary=1; +void print_results() +{ + struct timespec end; + print_bests(); + set_timer(&end); + if (displaysummary) + printf("Total time elapsed: %.5f secs, nodes/leaves evaluated:%'d/%'d\n", + get_timer(end), get_totnodes(), get_totleaves()); +} + void usage() { fprintf(stderr, "usage: %s [options] target n1 n2 [...n%d]\n", cmd, MAXINPUT); @@ -32,6 +42,7 @@ void help() { usage(); fprintf(stderr, "Countdown game solver.\n"); + fprintf(stderr, " -1: Stops immediately when one solution is found\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"); @@ -64,10 +75,9 @@ int main(ac, av) TREE *tree; char intarray[1024]; char *comb; - struct timespec end; - char *options="thcisd:"; + char *options="1thcisd:"; int option; -# ifdef DEBUG_MAIN +# ifdef DEBUG_MAINLOOP int eval; # endif @@ -76,6 +86,9 @@ int main(ac, av) while ((option = getopt(ac, av, options)) != -1) { //printf("opt: %c\n", option); switch (option) { + case '1': + firstonly=1; + break; case 'd': switch(*optarg) { case 'r': @@ -135,50 +148,30 @@ int main(ac, av) nops=stacksize-1; gen_combinations(nops); - //ncombs=ncombinations(len_ops, nops); ncombs=n_combs(); - //print_combs(); - 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=optind+1; istack, 0, stack->last-1); - //print_stack(stack, 1); - - /*i=1; - do { - printf("permutation %2d: ", i++); - print_stack(stack, 0); - } while (permute_stack(stack->stack, stack->last)); - */ + gen_stacks(&inputstack); if (treetype==TREE_CATALAN) { gen_tree(intarray, nops, 0, 0); } else { gen_reduced_trees(nops); } + set_target(target); + set_intr(); + nstacks=n_stacks(); ntrees=n_trees(); +# ifdef DEBUG_MAIN 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); if (eval > 0) { - printf("============================== %d, %d, %d\n", i, j, k); - print_tree(tree, 0); - print_comb(j); - print_stack(stack, 0); - printf("eval=%d - calcs=%d\n", eval, ncalcs); - + printf("================= mainloop tree=%d, comb=%d, stack=%d\n", i, j, k); + printf("mainloop: ");print_tree(tree, 0); + printf("mainloop: ");print_comb(j); + printf("mainloop: "); print_stack(stack, 0); + printf("mainloop: eval=%d - calcs=%d\n", eval, ncalcs); } # else eval_node(tree->head, 0, stack->stack, comb, &ncalcs); +# endif +# ifdef DEBUG_MAINSLEEP + sleep(1); # endif } } @@ -214,11 +206,7 @@ int main(ac, av) //res=eval_stack(stack); //printf("EVAL=%d\n", res); } - printf("\n"); - print_bests(); - set_timer(&end); - if (displaysummary) - printf("Total time elapsed: %.5f secs, nodes/leaves evaluated:%'d/%'d\n", - get_timer(end), get_totnodes(), get_totleaves()); + //printf("\n"); + print_results(); exit(0); } diff --git a/lceb.h b/lceb.h index d1e5fa6..681c567 100644 --- a/lceb.h +++ b/lceb.h @@ -65,6 +65,13 @@ typedef struct best { struct timespec timer; } BEST; +/* lceb.c */ +extern void print_results(); + +/* signal.c */ +extern void set_intr(); +extern int stopped(); + /* tree.c */ extern NODE *get_node(); extern void free_node(NODE *node); @@ -119,7 +126,6 @@ extern int get_totnodes(); extern int get_totleaves(); /* best.c */ -extern int stopped(); extern void set_target (int n); extern int check_best(int res, int nops, NODE *node, int *values, char *ops); extern void print_best(NODE *node, int *values, char *pops, int depth); diff --git a/signal.c b/signal.c new file mode 100644 index 0000000..e642399 --- /dev/null +++ b/signal.c @@ -0,0 +1,23 @@ +#include +#include + +int sigint_received=0; + +static void stopall() +{ + printf("SIGINT RECEIVED: aborting eval\n"); + sigint_received=1; +} + +int stopped() +{ + return sigint_received; +} + +void set_intr() +{ + signal(SIGINT, stopall); +# ifdef DEBUG + printf("SIGINT armed.\n"); +# endif +} diff --git a/stack.c b/stack.c index f438537..e91aaa4 100644 --- a/stack.c +++ b/stack.c @@ -52,7 +52,7 @@ STACK *new_stack(size, name, keep) STACK *stack; int i; -# ifdef DEBUG_STACK +# ifdef DEBUG_STACK2 printf("new_stack(size=%d, name=[%s] last=%d total=%d)\n", size, name, laststack, totalstacks); # endif @@ -105,7 +105,7 @@ int *push_stack(stack, val) int size=stack->size; int *pelt=stack->stack+stack->last; -# ifdef DEBUG_STACK +# ifdef DEBUG_STACK2 printf("push_stack(%d:[%s]): last=%d size=%d\n", val, stack->name, stack->last, stack->size); # endif @@ -201,34 +201,24 @@ void gen_stacks(stack) int n=1; 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); +# ifdef DEBUG_STACK + printf("generating stacks...\n"); +# endif + //printf("last=%d laststack=%d totalstacks=%d\n", last, laststack, totalstacks); +# ifdef DEBUG_STACK + printf("sorting initial stack...\n"); +# endif 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... "); +# ifdef DEBUG_STACK + print_stack(stack, 0); +# endif dup_stack(stack, "Main stack"); - //keep_stack(new); - //print_stacks(); - //print_stack(stack, 1); while (exists) { sprintf(name, "Stack copy %d", n); - //new=dup_stack(new, name); exists=permute_stack(stack->stack, stack->last); - //printf("Permute : "); - //print_stack(stack, 0); if (exists) { - //printf("++++++++++++++++ Adding stack... "); dup_stack(stack, name); - // print_stack(new, 0); - //keep_stack(new); } -// printf("---------------------- Stack... "); -// print_stacks(); n++; } }