0

Imagine I have four letters a,b,c and d. I want to determine what are the ways to validly parenthesize and multiply them. For instance (a.b).(c.d) can be a solution or (a.(b.c)).d another solution. The number of combinations is 5 for 4 letters. (Which is also equivalent to Catalan Number n-1 in that case catalan number 3 which is 5).

I have realized that these combinations can be written as full binary trees and each binary tree represents one combination :

 abcd                abcd                
  /  \                / \      .....
 /    \              /   \
a     bcd           ab    cd
       / \          / \   /\
      bc  d        a   b c  d
      / \
     b   c

Starting from the deepest leaf, algorithm can generate for instance for the first tree : 1 - (b.c) then 2 - (b.c).d then 3- a.((b.c).d).

I want to have a recursive or normal function which can generate all the possible trees and do the multiplications but not sure how I can achieve that. Any help and suggestion is greatly appreciated.

ayt_cem
  • 105
  • 1
  • 9
  • 1
    Similar: [How to print all possible balanced parentheses for an expression?](http://stackoverflow.com/questions/6447289/how-to-print-all-possible-balanced-parentheses-for-an-expression) – abhishekkannojia Mar 28 '17 at 14:08
  • 3
    Are you aware of the tag [tag:catalan]? You should also be aware of the tag [tag:recurrence-relation]. – Guy Coder Mar 28 '17 at 14:10
  • Multiplication is associative. Wouldn't all parenthetical arrangements turn out the same if only multiplication is used? – גלעד ברקן Mar 28 '17 at 14:12
  • Imagine that it is matrix multiplication or any other operation in that case the order is important – ayt_cem Mar 28 '17 at 14:12
  • You need to make the distinction in the question that the binary trees are full binary trees. It is obvious from the problem because you are only using a binary operator, but if you introduce a unary operator then you get the [Motzkin numbers](https://en.wikipedia.org/wiki/Motzkin_number) instead. – Guy Coder Mar 28 '17 at 14:16
  • I am just trying to say that (a.b).c or a.(b.c) gives different results in my project because they are different operations than multiplication. – ayt_cem Mar 28 '17 at 14:17
  • Binary Trees are full binary trees yes. – ayt_cem Mar 28 '17 at 14:18
  • 1
    I see from your other [question](http://stackoverflow.com/q/41990386/1243762) you are working on the same problem. The only difference is the output format. – Guy Coder Mar 28 '17 at 14:18
  • Binary trees can have unary branches. From [Wikipedia](https://en.wikipedia.org/wiki/Binary_tree) `a binary tree is a tree data structure in which each node has at most two children`. In other words full binary trees are related to Catalan numbers and binary trees, e.g. have unary branches, are related to Motzkin numbers. The difference is significant. – Guy Coder Mar 28 '17 at 14:21
  • 1
    If you look at the tag info for [tag:catalan] you will find a link to [Catalan Numbers and Grouping with Parenthesis](http://people.math.sc.edu/howard/Classes/554b/catalan.pdf), very informative. – Guy Coder Mar 28 '17 at 14:23
  • 1
    Of interest: [Code Golf](http://codegolf.stackexchange.com/q/112874/66444) – Guy Coder Mar 28 '17 at 14:26
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/139265/discussion-between-ayt-cem-and-guy-coder). – ayt_cem Mar 28 '17 at 14:35

1 Answers1

0

Here's a JavaScript adaptation of ninjagecko's Python code from How to print all possible balanced parentheses for an expression?

function associations(seq, kw){   
  var grouper = kw.grouper || ((a,b) => [a,b]),
      lifter = kw.lifter || (x => [x]);

  if (seq.length === 1){
    return lifter(seq[0]);
   
  } else {
    var result = [];
  
    for (let i=1; i<seq.length; i++){
      // split sequence on index i
      var left = seq.slice(0,i),
          right = seq.slice(i);

      // return cartesian product of left x right
      for (let l of associations(left,kw))
        for (let r of associations(right,kw))
          result.push(grouper(l,r));
    }   
    return result;
  }
}
 
console.log(JSON.stringify(associations([1,2,3,4],{})));
Community
  • 1
  • 1
גלעד ברקן
  • 23,602
  • 3
  • 25
  • 61
  • Yes I think this code will be very useful.This code generates all possible paranthesis and later on, for each combination ( for each [ ], I have to make an operation. For instance I will take [ [ 1,[2, [3,4]]] and do operation [3,4] then operation [2,[3,4]] then operation [ 1,[2, [3,4]]. To do that I guess I have to parse this result object which is like arrays of arrays ? – ayt_cem Mar 30 '17 at 14:58
  • @ayt_sem I think you may be able to use the 'grouper' and 'lifter' functions to perform the operation, then each inner expression will already be returned as evaluated. Try and see. (So the inner 3,4 will already be multiplied, for example, instead of returning [3,4], it will return 12.) – גלעד ברקן Mar 30 '17 at 16:50
  • Do I have to include a library to use these grouper and lifter functions ? – ayt_cem Mar 30 '17 at 17:05
  • @ayt_sem no, they are defined by you :) In the second parameter of the function, you pass an object with properties, 'grouper', and 'lifter' functions. If they are not defined, they default to the ones you see in the beginning of the code as `kw.grouper` and `kw.lifter`. – גלעד ברקן Mar 30 '17 at 17:24
  • Can you explain to me what the kw.grouper and kw.lifter do please ? – ayt_cem Mar 31 '17 at 00:15