simplify # trees: Catalan trees -> Wedderburn–Etherington trees
This commit is contained in:
22
Makefile
22
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
|
||||
|
45
eval.c
45
eval.c
@@ -1,4 +1,5 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#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:
|
||||
|
16
lceb.c
16
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; i<ac; ++i) {
|
||||
val=atoi(av[i]);
|
||||
push_stack(&inputstack, val);
|
||||
@@ -66,7 +73,8 @@ int main(ac, av)
|
||||
} while (permute_stack(stack->stack, 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",
|
||||
|
37
lceb.h
37
lceb.h
@@ -1,8 +1,11 @@
|
||||
#include <time.h>
|
||||
|
||||
#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();
|
||||
|
||||
|
2
oper.c
2
oper.c
@@ -1,3 +1,5 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include "lceb.h"
|
||||
|
4
stack.c
4
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;
|
||||
|
7
timer.c
7
timer.c
@@ -1,4 +1,5 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#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));
|
||||
|
146
tree.c
146
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; i<size; ++i)
|
||||
printf("%c", desc[i]);
|
||||
putchar('\n');
|
||||
# endif
|
||||
root=get_node();
|
||||
root->type=TREE_NODE;
|
||||
nodestack[curnode++]=root;
|
||||
|
||||
for(i=1; i<size; ++i) {
|
||||
node = get_node();
|
||||
if (desc[i-1]) {
|
||||
if (desc[i-1]=='1') {
|
||||
nodestack[curnode-1]->left = 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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user