From d72eb84347c8bbd6e5820fd92d93805d0cb4a904 Mon Sep 17 00:00:00 2001 From: Bruno Raoult Date: Mon, 25 Jan 2021 15:13:22 +0100 Subject: [PATCH] fix display, add trees optimisation text. --- REDUCE-TREES.txt | 249 +++++++++++++++++++++++++++++++++++++++++++++++ timer.c | 1 + tree.c | 38 +++++--- 3 files changed, 274 insertions(+), 14 deletions(-) create mode 100644 REDUCE-TREES.txt diff --git a/REDUCE-TREES.txt b/REDUCE-TREES.txt new file mode 100644 index 0000000..0b6495e --- /dev/null +++ b/REDUCE-TREES.txt @@ -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 diff --git a/timer.c b/timer.c index 3b165dc..eb83785 100644 --- a/timer.c +++ b/timer.c @@ -5,6 +5,7 @@ #define NANOSEC 1000000000.0 #define MILLISEC 1000 +int displaytimer=0; static struct timespec start; void start_timer() diff --git a/tree.c b/tree.c index 6c6135f..27aafdd 100644 --- a/tree.c +++ b/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; ileft=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); }