simplify # trees: Catalan trees -> Wedderburn–Etherington trees

This commit is contained in:
2021-01-25 10:12:45 +01:00
parent 684c33f156
commit 507988a93b
8 changed files with 203 additions and 76 deletions

View File

@@ -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

35
eval.c
View File

@@ -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) {
@@ -67,16 +68,34 @@ int eval_node(node, depth, pvals, pops, ncalcs)
res=val1*val2;
break;
case Sub:
if (val1 > val2)
if (val1 != val2) {
if (val1 > val2) {
res=val1-val2;
if (res == val2) /* we already got this value in tree */
} 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))
if (val1 >= val2) {
if (val2 != 1 && (val1 % val2 == 0))
res=val1/val2;
if (res == val2) /* we already got this value in tree */
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
View File

@@ -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",

27
lceb.h
View File

@@ -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',
@@ -32,12 +35,15 @@ typedef struct stack {
typedef struct node {
int type; /* TREE_LEAF or TREE_NODE */
int op;
int val;
int eval;
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 {
@@ -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
View File

@@ -1,3 +1,5 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include "lceb.h"

View File

@@ -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;

View File

@@ -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));

138
tree.c
View File

@@ -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;
}
/* 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)
int *seq;
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;
ntrees++;
# ifdef DEBUG1
printf("tree %d desc=", ntrees);
for (i=0; i<=2*n; ++i)
printf("%d", seq[i]);
putchar('\n');
# 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++;
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);
}