fix display, add trees optimisation text.
This commit is contained in:
249
REDUCE-TREES.txt
Normal file
249
REDUCE-TREES.txt
Normal file
@@ -0,0 +1,249 @@
|
||||
I thought about a way to drastically reduce the number of necessary trees. Does it make sense ?
|
||||
|
||||
For a 5 leaves (numbers) and 4 operators, I define following tree types:
|
||||
|
||||
;; Type A
|
||||
o
|
||||
/ \
|
||||
o
|
||||
/ \
|
||||
o
|
||||
/ \
|
||||
o
|
||||
/ \
|
||||
|
||||
;; type B
|
||||
o
|
||||
/ \
|
||||
o o
|
||||
/ \ / \
|
||||
o
|
||||
/ \
|
||||
|
||||
|
||||
;; Type C
|
||||
o
|
||||
/ \
|
||||
o
|
||||
/ \
|
||||
o o
|
||||
/ \ / \
|
||||
|
||||
Normally, we have 14 trees for 5 numbers. But I categorize them within the 3 types above.
|
||||
|
||||
What I think is: 2 trees of same type will find the same solutions, given we permute all operators and numbers :
|
||||
- It looks trivial for operators '+' and '-'.
|
||||
- For '/' et '-', if we swap subtrees numbers to always have maximum on the left, we are left with always one operation (if possible), so the order does not matter.
|
||||
|
||||
My generated trees generated (in tree.c) for 5 numbers are :
|
||||
1: (Op x (Op x (Op x (Op x x))))
|
||||
2: (Op x (Op x (Op (Op x x) x)))
|
||||
3: (Op x (Op (Op x x) (Op x x)))
|
||||
4: (Op x (Op (Op x (Op x x)) x))
|
||||
5: (Op x (Op (Op (Op x x) x) x))
|
||||
6: (Op (Op x x) (Op x (Op x x)))
|
||||
7: (Op (Op x x) (Op (Op x x) x))
|
||||
8: (Op (Op x (Op x x)) (Op x x))
|
||||
9: (Op (Op x (Op x (Op x x))) x)
|
||||
10: (Op (Op x (Op (Op x x) x)) x)
|
||||
11: (Op (Op (Op x x) x) (Op x x))
|
||||
12: (Op (Op (Op x x) (Op x x)) x)
|
||||
13: (Op (Op (Op x (Op x x)) x) x)
|
||||
14: (Op (Op (Op (Op x x) x) x) x)
|
||||
|
||||
Categories:
|
||||
|
||||
;; 1 : type A
|
||||
(Op x o
|
||||
(Op x / \
|
||||
(Op x o
|
||||
(Op x / \
|
||||
x)))) o
|
||||
/ \
|
||||
o
|
||||
/ \
|
||||
|
||||
;; 2 : Type A
|
||||
(Op x o
|
||||
(Op x / \
|
||||
(Op o
|
||||
(Op x / \
|
||||
x) o
|
||||
x))) / \
|
||||
o
|
||||
/ \
|
||||
;; 3 : Type C
|
||||
(Op x o
|
||||
(Op / \
|
||||
(Op x o
|
||||
x) / \
|
||||
(Op x o o
|
||||
x))) / \ / \
|
||||
|
||||
;; 4 : Type A
|
||||
o
|
||||
(Op x / \
|
||||
(Op o
|
||||
(Op x / \
|
||||
(Op x o
|
||||
x)) / \
|
||||
x)) o
|
||||
/ \
|
||||
;; 5 : Type A
|
||||
(Op x o
|
||||
(Op / \
|
||||
(Op o
|
||||
(Op x / \
|
||||
x) o
|
||||
x) / \
|
||||
x)) o
|
||||
/ \
|
||||
|
||||
;; 6 : Type B
|
||||
(Op o
|
||||
(Op x / \
|
||||
x) o o
|
||||
(Op x / \ / \
|
||||
(Op x o
|
||||
x))) / \
|
||||
|
||||
;; 7 : Type B
|
||||
(Op o
|
||||
(Op x / \
|
||||
x) o o
|
||||
(Op / \ / \
|
||||
(Op x o
|
||||
x) / \
|
||||
x))
|
||||
|
||||
;; 8 : Type B
|
||||
(Op o
|
||||
(Op x / \
|
||||
(Op x o o
|
||||
x)) / \ / \
|
||||
(Op x o
|
||||
x)) / \
|
||||
|
||||
;; 9 : Type A
|
||||
(Op o
|
||||
(Op x / \
|
||||
(Op x o
|
||||
(Op x / \
|
||||
x))) o
|
||||
x) / \
|
||||
o
|
||||
/ \
|
||||
|
||||
;; 10 : Type A
|
||||
(Op o
|
||||
(Op x / \
|
||||
(Op o
|
||||
(Op x / \
|
||||
x) o
|
||||
x)) / \
|
||||
x) o
|
||||
/ \
|
||||
;; 11 : Type B
|
||||
(Op o
|
||||
(Op / \
|
||||
(Op x o o
|
||||
x) / / \
|
||||
x) o
|
||||
(Op x / \
|
||||
x))
|
||||
|
||||
;; 12 : Type C
|
||||
(Op o
|
||||
(Op / \
|
||||
(Op x o
|
||||
x) / \
|
||||
(Op x o o
|
||||
x)) / \ / \
|
||||
x)
|
||||
|
||||
;; 13 : Type A
|
||||
(Op o
|
||||
(Op / \
|
||||
(Op x o
|
||||
(Op x / \
|
||||
x)) o
|
||||
x) / \
|
||||
x) o
|
||||
/ \
|
||||
;; 14 : Type A
|
||||
(Op o
|
||||
(Op / \
|
||||
(Op o
|
||||
(Op x / \
|
||||
x) o
|
||||
x) / \
|
||||
x) o
|
||||
x) / \
|
||||
|
||||
|
||||
Below are all categories by input of N numbers, for N={2,3,4,5,6} :
|
||||
|
||||
w is max leaves on same level, and h is height (distance from root to lowest leaf).
|
||||
|
||||
2 leaves (1, Catalan=1):
|
||||
|
||||
o
|
||||
/ \
|
||||
|
||||
width=2, height=1
|
||||
|
||||
3 leaves (1, Catalan=2):
|
||||
o
|
||||
/ \
|
||||
o
|
||||
/ \
|
||||
|
||||
w=2, h=2
|
||||
|
||||
4 leaves (2, Catalan=5):
|
||||
o o
|
||||
/ \ / \
|
||||
o o o
|
||||
/ \ / \ / \
|
||||
o
|
||||
/ \
|
||||
|
||||
w=2, h=3 w=4, h=2
|
||||
|
||||
5 leaves (3, Catalan=14):
|
||||
|
||||
o o o
|
||||
/ \ / \ / \
|
||||
o o o o
|
||||
/ \ / \ / \ / \
|
||||
o o o o
|
||||
/ \ / \ / \ / \
|
||||
o
|
||||
/ \
|
||||
|
||||
w=2, h=4 w=3, h=3 w=4, h=3
|
||||
|
||||
6 leaves (6, Catalan=42):
|
||||
|
||||
o o o o
|
||||
/ \ / \ / \ / \
|
||||
o o o o o
|
||||
/ \ / \ / \ / \ / \
|
||||
o o o o o
|
||||
/ \ / \ / \ / \ / \
|
||||
o o o o o
|
||||
/ \ / \ / \ / \ / \
|
||||
o
|
||||
/ \
|
||||
|
||||
w=2, h=5 w=3, h=4 w=3, h=4 w=4, h=4
|
||||
|
||||
|
||||
o o
|
||||
/ \ / \
|
||||
o o o o
|
||||
/ \ / \ / \ / \
|
||||
o o o o
|
||||
/ \ / \ / \ / \
|
||||
|
||||
w=4, h=3 w=4, h=3
|
1
timer.c
1
timer.c
@@ -5,6 +5,7 @@
|
||||
#define NANOSEC 1000000000.0
|
||||
#define MILLISEC 1000
|
||||
|
||||
int displaytimer=0;
|
||||
static struct timespec start;
|
||||
|
||||
void start_timer()
|
||||
|
38
tree.c
38
tree.c
@@ -15,9 +15,11 @@ NODE *get_node()
|
||||
|
||||
if (!freenodes) {
|
||||
register int i;
|
||||
freenodes=malloc(ALLOCSIZE*sizeof(NODE));
|
||||
totnodes+=ALLOCSIZE;
|
||||
printf("allocating %d nodes - total nodes=%d\n", ALLOCSIZE, totnodes);
|
||||
# ifdef DEBUG_MEM
|
||||
printf("get_node: allocating %d new nodes - total nodes=%d\n", ALLOCSIZE, totnodes);
|
||||
# endif
|
||||
freenodes=malloc(ALLOCSIZE*sizeof(NODE));
|
||||
for (i=0; i<ALLOCSIZE-1; ++i) { /* create chained list */
|
||||
(freenodes+i)->left=NULL;
|
||||
(freenodes+i)->right=NULL;
|
||||
@@ -74,6 +76,7 @@ void print_node(node, side, depth, details)
|
||||
print_node(node->right, TREE_RIGHT, depth+1, details);
|
||||
break;
|
||||
case 0:
|
||||
case 5:
|
||||
print_node(node->left, TREE_LEFT, depth+1, details);
|
||||
print_node(node->right, TREE_RIGHT, depth+1, details);
|
||||
if (node->type==TREE_NODE) {
|
||||
@@ -81,6 +84,8 @@ void print_node(node, side, depth, details)
|
||||
} else {
|
||||
printf("%d ", node->val);
|
||||
}
|
||||
if (details==5 && depth==0)
|
||||
printf("p");
|
||||
break;
|
||||
case 3:
|
||||
if (node->type==TREE_NODE) {
|
||||
@@ -127,7 +132,6 @@ void print_node(node, side, depth, details)
|
||||
print_node(node->left, TREE_LEFT, depth+1, details);
|
||||
print_node(node->right, TREE_RIGHT, depth+1, details);
|
||||
break;;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,7 +139,6 @@ void print_tree(tree, details)
|
||||
TREE *tree;
|
||||
int details;
|
||||
{
|
||||
int i;
|
||||
switch (details) {
|
||||
case 2:
|
||||
print_node(tree->head, TREE_TOP, 0, details);
|
||||
@@ -377,24 +380,31 @@ int n_trees()
|
||||
}
|
||||
|
||||
#ifdef STANDALONE
|
||||
void main(ac, av)
|
||||
int main(ac, av)
|
||||
int ac;
|
||||
char **av;
|
||||
{
|
||||
int n, details=0;
|
||||
int n, details=0, type=0;
|
||||
char 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");
|
||||
if (ac<3 || ac>4) {
|
||||
fprintf(stderr, "usage: %s type nodes [display]\n", *av);
|
||||
fprintf(stderr, "type : 0 for Catalan, 1 for Wedderburn\n");
|
||||
fprintf(stderr, "display can be 0 (RPN, default, 1 (polish), 2 (details), 3 (lisp notation), 4 (parenthesed notation)\n");
|
||||
exit (1);
|
||||
}
|
||||
if (ac==3) {
|
||||
details=atoi(av[2]);
|
||||
if (ac==4) {
|
||||
details=atoi(av[3]);
|
||||
}
|
||||
type=atoi(av[1]);
|
||||
n=atoi(av[2]);
|
||||
if (type == 0) {
|
||||
printf("generating Calalan tree...\n");
|
||||
gen_tree(array, n, 0, 0);
|
||||
} else {
|
||||
printf("generating Wedderburn tree...\n");
|
||||
gen_reduced_trees(n+1);
|
||||
}
|
||||
n=atoi(av[1]);
|
||||
gen_reduced_trees(n+1);
|
||||
//gen_tree(array, n, 0, 0);
|
||||
print_trees(details);
|
||||
exit(0);
|
||||
}
|
||||
|
Reference in New Issue
Block a user