diff --git a/Makefile b/Makefile index 9893d08..82a4eaf 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,12 @@ SHELL := /bin/bash #CFLAGS := -w -O3 -pg -DDEBUG -DDEBUG_BEST -CFLAGS := -w -O3 -DDEBUG -DDEBUG_BEST +CFLAGS := -O3 -DDEBUG -DDEBUG_BEST -DDEBUG_TREE -DDEBUG_STACK # specific DEBUG flags: # timer: -DDEBUG_TIMER # best control: -DDEBUG_BEST +# tree: -DDEBUG_TREE +# stack: -DDEBUG_STACK +# stack: -DDEBUG_EVAL -DDEBUG_EVAL2 #CFLAGS := -w -g -pg -DDEBUG TIME := \time -f "\ttime: %E real, %U user, %S sys\n\tcontext-switch:\t%c+%w, page-faults: %F+%R\n" @@ -18,22 +21,17 @@ OBJS=$(TARGETS:=.o) all: $(TARGETS) lceb: $(OBJS) - $(CC) $(CFLAGS) -DSTANDALONE -o $@ $^ + $(CC) $(CFLAGS) -o $@ $^ +tree oper timer: lceb.h tree: tree.c - $(CC) $(CFLAGS) -DSTANDALONE -o $@ $? + $(CC) $(CFLAGS) -DSTANDALONE -o $@ $< oper: oper.c - $(CC) $(CFLAGS) -DSTANDALONE -o $@ $? + $(CC) $(CFLAGS) -DSTANDALONE -o $@ $< timer: timer.c - $(CC) $(CFLAGS) -DSTANDALONE -o $@ $? + $(CC) $(CFLAGS) -DSTANDALONE -o $@ $< -lceb.o tree.o oper.o eval.o stack.o best.o: lceb.h -tree oper: lceb.h - -ex2: ex2-c - @$(TIME) ex2-c < $(INPUT) - -%.o: %.c $(INCLUDES) +lceb.o tree.o oper.o eval.o stack.o best.o timer.o: lceb.h clean: rm -f $(TARGETS) $(OBJS) core diff --git a/eval.c b/eval.c index c2d0997..0fd1cc5 100644 --- a/eval.c +++ b/eval.c @@ -1,4 +1,5 @@ #include +#include #include "lceb.h" @@ -14,7 +15,7 @@ int eval_node(node, depth, pvals, pops, ncalcs) { static int *vals, *val_zero; static char *ops, *ops_zero; - static *node_zero; + static NODE *node_zero; static int totcalc; int val1, val2, op, res=-1, i, lcalcs, rcalcs; @@ -24,16 +25,16 @@ int eval_node(node, depth, pvals, pops, ncalcs) node_zero=node; totcalc=0; } -# ifdef DEBUG1 +# ifdef DEBUG_EVAL for (i=0; i<=depth; ++i) printf(" "); - printf("eval : depth=%d : ncalcs=%d", depth, *ncalcs); + printf("eval : depth=%d : ncalcs=%d ", depth, *ncalcs); if (node->type == TREE_NODE) { printf("node(%c)\n", *ops); print_node(node, TREE_TOP, 0, 0); } else { - printf("val(%d)\n", *vals); + printf("leaf(%d)\n", *vals); } # endif if (node->type == TREE_LEAF) { @@ -63,20 +64,38 @@ int eval_node(node, depth, pvals, pops, ncalcs) res=val1+val2; break; case Mul: - if (val1 > 1 && val2 > 1) /* we avoid "x*1" */ + if (val1 > 1 && val2 > 1) /* we avoid "x*1" */ res=val1*val2; break; case Sub: - if (val1 > val2) - res=val1-val2; - if (res == val2) /* we already got this value in tree */ - res=-1; + if (val1 != val2) { + if (val1 > val2) { + res=val1-val2; + } else { +# ifdef DEBUG_EVAL2 + printf("eval: Sub: swapping val1=%d val2=%d\n", val1, val2); +# endif + res=val2-val1; + } + if (res == val2) /* already found in subtree */ + res=-1; + } break; case Div: - if (val1 >= val2 && val2 != 1 && (val1 % val2 == 0)) - res=val1/val2; - if (res == val2) /* we already got this value in tree */ - res=-1; + if (val1 >= val2) { + if (val2 != 1 && (val1 % val2 == 0)) + res=val1/val2; + if (res == val2) /* already found in subtree */ + res=-1; + } else { +# ifdef DEBUG_EVAL2 + printf("eval: Div: swapping val1=%d val2=%d\n", val1, val2); +# endif + if (val1 != 1 && (val2 % val1 == 0)) + res=val2/val1; + if (res == val1) /* already found in subtree */ + res=-1; + } break; case Nop: case End: diff --git a/lceb.c b/lceb.c index c8c1b87..83fcbda 100644 --- a/lceb.c +++ b/lceb.c @@ -20,11 +20,18 @@ int main(ac, av) char **av; { unsigned target; - STACK inputstack, *stack; + STACK inputstack = { + "initial", + MAXINPUT, /* size */ + 0, /* last */ + NULL, /* next */ + {0} + }; + STACK *stack; int i, j, k, stacksize, val; int ncombs, nstacks, ntrees, nops; TREE *tree; - int intarray[1024]; + char intarray[1024]; int eval; char *comb; struct timespec end; @@ -47,7 +54,7 @@ int main(ac, av) 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"); + //strcpy(inputstack.name, "initial"); for (i=2; istack, stack->last)); */ - gen_tree(intarray, nops, 0, 0); + //gen_tree(intarray, nops, 0, 0); + gen_reduced_trees(nops+1); nstacks=n_stacks(); ntrees=n_trees(); printf("stacks=%d\noperators combinations=%d\ntrees=%d\n", diff --git a/lceb.h b/lceb.h index 7421cfe..c161441 100644 --- a/lceb.h +++ b/lceb.h @@ -1,8 +1,11 @@ #include -#define MAXINPUT 6 /* max numbers as input */ -#define ALLOCSIZE 1024 /* # of elements to alloc when needed */ -#define EMPTY -1 +#define MAXINPUT (6) /* max numbers as input */ +#define ALLOCSIZE (1024) /* # of elements to alloc */ + +#define MIN(a,b) (((a)<(b))?(a):(b)) +#define MAX(a,b) (((a)>(b))?(a):(b)) +#define ABS(a) (((a)<0)?-(a):(a)) typedef enum { Nop='N', @@ -21,7 +24,7 @@ typedef struct stack { int stack[MAXINPUT+1]; } STACK; -#define TREE_UNDEF (-1) /* should not happen */ +#define TREE_UNDEF (-1) /* should not happen */ #define TREE_LEAF 0 #define TREE_NODE 1 #define TREE_LEFT 'L' @@ -31,22 +34,25 @@ typedef struct stack { #define EMPTY -1 typedef struct node { - int type; /* TREE_LEAF or TREE_NODE */ - int op; - int val; - int eval; + int type; /* TREE_LEAF or TREE_NODE */ + int op; /* operator (nodes only) */ + int val; /* value (leafs only) */ + int eval; /* eval (unused) */ + int prof; /* max left/right profs */ + int left_prof; struct node *left; + int right_prof; struct node *right; - struct node *next; /* for transversal walk and free nodes */ + struct node *next; /* for transv walk and free nodes */ } NODE; typedef struct tree { char name[80]; NODE *head; struct tree *next; - int nodes; /* number of nodes */ - int leaves; /* number of leaves */ - int depth; /* max depth */ + int nodes; /* number of nodes */ + int leaves; /* number of leaves */ + int depth; /* max depth */ } TREE; typedef struct best { @@ -67,8 +73,11 @@ extern void print_tree(TREE *tree, int details); extern void print_trees(int details); extern TREE *new_tree(char *name); extern NODE *dup_node(NODE *src); -extern NODE *build_tree(int *desc, int size); -extern void gen_tree(int *seq, int n, int nb1, int nb0); +//extern NODE *build_tree(int *desc, int size); +extern NODE *build_tree(char *desc, int size); +//extern void gen_tree(int *seq, int n, int nb1, int nb0); +extern void gen_reduced_trees(int n); +extern void gen_tree(char *seq, int n, int nb1, int nb0); extern TREE *nth_tree(int n); extern int n_trees(); diff --git a/oper.c b/oper.c index 2acfb55..8e600ba 100644 --- a/oper.c +++ b/oper.c @@ -1,3 +1,5 @@ +#include +#include #include #include #include "lceb.h" diff --git a/stack.c b/stack.c index 2901a0e..a9e6a93 100644 --- a/stack.c +++ b/stack.c @@ -107,6 +107,10 @@ 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 + if (pos >= size) { fprintf(stderr, "stack overflow: size=%d last=%d\n", size, pos); return NULL; diff --git a/timer.c b/timer.c index 6a931f7..3b165dc 100644 --- a/timer.c +++ b/timer.c @@ -1,4 +1,5 @@ #include +#include #include #define NANOSEC 1000000000.0 @@ -20,7 +21,7 @@ void set_timer(timer) { clock_gettime(CLOCK_MONOTONIC, timer); # ifdef DEBUG_TIMER - printf("timer: sec=%d nsec=%d orig: sec=%d nsec=%d\n", + printf("timer: sec=%d nsec=%d orig: sec=%ld nsec=%ld\n", timer->tv_sec, timer->tv_nsec, start.tv_sec, start.tv_nsec); # endif } @@ -37,7 +38,7 @@ double get_timer(timer) } #ifdef STANDALONE -main(ac, av) +int main(ac, av) int ac; char **av; { @@ -52,7 +53,7 @@ main(ac, av) start_timer(); tsdelay.tv_sec=delay/MILLISEC; tsdelay.tv_nsec=delay%MILLISEC; - printf("delay %d=%d:%d\n", delay, tsdelay.tv_sec, tsdelay.tv_nsec); + printf("delay %d=%ld:%ld\n", delay, tsdelay.tv_sec, tsdelay.tv_nsec); nanosleep(&tsdelay, NULL); set_timer(&end); printf("Time elapsed: %.5f seconds\n", get_timer(end)); diff --git a/tree.c b/tree.c index 5b6e3b4..6c6135f 100644 --- a/tree.c +++ b/tree.c @@ -194,41 +194,49 @@ NODE *dup_node(src) return dst; } -/*void free_node(node) +/* untested - unused */ +int calc_prof_node(node) NODE *node; { + int left, right; + if (node->type==TREE_LEAF) { - node->next=freenodes; - freenodes=node; + return 0; } else { - free_node(node->left); - free_node(node->right); - node->next=freenodes; - freenodes=node; + left=calc_prof_node(node->left); + right=calc_prof_node(node->right); + node->prof=MAX(left, right)+1; } - }*/ + return node->prof; +} NODE *build_tree(desc, size) - int *desc; + char *desc; int size; { NODE *root, *node; NODE *nodestack[1024]; /* TODO: make it dynamic */ int i, curnode=0; +# ifdef DEBUG_TREE + printf("tree %d desc=", ntrees); + for (i=0; itype=TREE_NODE; nodestack[curnode++]=root; for(i=1; ileft = node; } else { nodestack[curnode-1]->right = node; curnode--; } - if (desc[i]) { + if (desc[i]=='1') { node->type=TREE_NODE; nodestack[curnode++]=node; } else { @@ -239,25 +247,102 @@ NODE *build_tree(desc, size) return root; } -void gen_tree(seq, n, nb1, nb0) - int *seq; - int n; /* number of nodes */ - int nb1; /* number of "1" */ - int nb0; /* number of "0" */ +/* generate reduced trees from static description */ +void gen_reduced_trees(n) + int n; +{ + int size=n*2-1, i; + TREE *tree; + char name[80]; + char *seq2[]= { + "100" + }; + char *seq3[]= { + "10100" + }; + char *seq4[]= { + "1010100", + "1100100" + }; + char *seq5[]= { + "101010100", + "110010100", + "101100100" + }; + char *seq6[]= { + "10101010100", + "11001010100", + "10110010100", + "10101100100", + "11001100100", + "11010010100" + }; + + if (n<2 || n>MAXINPUT) { + fprintf(stderr, "gen_reduced_trees: wrong leaves %d\n", n); + return; + } +# ifdef DEBUG_TREE + printf("gen_reduced_trees(leaves=%d)\n", n); +# endif + + switch (n) { + case 2: + ntrees++; + sprintf(name, "Tree %d", ntrees); + tree=new_tree(name); + tree->head=build_tree(seq2[0], size); + break; + case 3: + ntrees++; + sprintf(name, "Tree %d", ntrees); + tree=new_tree(name); + tree->head=build_tree(seq3[0], size); + break; + case 4: + for (i=0; i<2; ++i) { + ntrees++; + sprintf(name, "Tree %d", ntrees); + tree=new_tree(name); + tree->head=build_tree(seq4[i], size); + } + break; + case 5: + for (i=0; i<3; ++i) { + ntrees++; + sprintf(name, "Tree %d", ntrees); + tree=new_tree(name); + tree->head=build_tree(seq5[i], size); + } + break; + case 6: + for (i=0; i<6; ++i) { + ntrees++; + sprintf(name, "Tree %d", ntrees); + tree=new_tree(name); + tree->head=build_tree(seq6[i], size); + } + break; + } + return; +} + +void gen_tree(seq, n, nb1, nb0) + char *seq; + int n; /* number of nodes */ + int nb1; /* number of "1" */ + int nb0; /* number of "0" */ { - int i; char name[80]; TREE *tree; - if((nb1 + nb0) == 2*n) { /* end */ - seq[2*n] = 0; +# ifdef DEBUG_TREE + printf("gen_tree(n=%d, nb1=%d, nb0=%d)\n", n, nb1, nb0); +# endif + if((nb1 + nb0) == 2*n) { /* end */ + seq[2*n] = '0'; + seq[2*n+1] = 0; ntrees++; -# ifdef DEBUG1 - printf("tree %d desc=", ntrees); - for (i=0; i<=2*n; ++i) - printf("%d", seq[i]); - putchar('\n'); -# endif sprintf(name, "Tree %d", ntrees); tree=new_tree(name); tree->head=build_tree(seq, 2*n+1); @@ -265,12 +350,12 @@ void gen_tree(seq, n, nb1, nb0) } if(nb1 >= nb0 && nb1 < n) { - seq[nb1+nb0] = 1; + seq[nb1+nb0] = '1'; gen_tree(seq, n, nb1+1, nb0); } if(nb0 < nb1 && nb1 <=n) { - seq[nb1+nb0] = 0; + seq[nb1+nb0] = '0'; gen_tree(seq, n, nb1, nb0+1); } } @@ -292,13 +377,13 @@ int n_trees() } #ifdef STANDALONE -main(ac, av) +void main(ac, av) int ac; char **av; { int n, details=0; + char array[1024]; - int array[1024]; if (ac<2 || ac>3) { fprintf(stderr, "usage: %s nodes [type]\n", *av); fprintf(stderr, "type can be 0 (RPN, default, 1 (polish), 2 (details), 3 (lisp notation), 4 (parenthesed notation)\n"); @@ -308,7 +393,8 @@ main(ac, av) details=atoi(av[2]); } n=atoi(av[1]); - gen_tree(array, n, 0, 0); + gen_reduced_trees(n+1); + //gen_tree(array, n, 0, 0); print_trees(details); exit(0); }