7
There are many types of binary operations, which can be categorized by their associative properties and their commutative properties.
A binary operation
()
is associative if the order of operations between operands does not affect the result — i.e. if(a(bc)) = ((ab)c)
.A binary operation
()
is commutative if the order of two operands within one operation does not affect the result — i.e. if(ab) = (ba)
.
There are operations like addition and multiplication that are both associative and commutative, and operations like subtraction and division that are neither associative nor commutative.
There are also operations — such as the group composition operator — that are associative but not commutative.
But then there are operations that are commutative but not associative. These are more rare and not analyzed as much mathematically, but they occur. For example, rounded multiplication is such an operation. If you round a calculation to the nearest tenth after every multiplication, you can get anomalies like (6.8 × 5.7) × 2.9 = 112.5
while 6.8 × (5.7 × 2.9) = 112.2
.
Let a permutation of the operands P
in an operation tree (such as ((x(xx))((x(xx))x))
) be associatively equivalent to another permutation Q
, if the operands in P
can be rearranged by the commutative property to form an operation tree identical to the original.
For example, permutations (a(b(c(de))))
and (a(b(c(ed))))
of the operation tree (x(x(x(xx))))
are equivalent, because d
commutes with e
. However, (a(b(c(de))))
and (a(b(d(ce))))
are not equivalent, because (c(de))
is not equal to (d(ce))
.
A more complex example might be (((ab)c)(d(ef)))
and (((ef)d)(c(ba)))
. Step-by-step, the two of these can be shown to be equivalent as follows:
(((ab)c)(d(ef))) = (((ba)c)(d(ef))) since a commutes with b
(((ba)c)(d(ef))) = (((ba)c)((ef)d)) since (ef) commutes with d
(((ba)c)((ef)d)) = ((c(ba))((ef)d)) since (ba) commutes with c
((c(ba))((ef)d)) = (((ef)d)(c(ba))) since (c(ba)) commutes with ((ef)d)
Permutations of different operation trees are not comparable. (a(b(c(de))))
and ((((ab)c)d)e)
are neither associatively equivalent nor associatively distinct, because their operation trees are different.
Your task is to build a program that will find all the associatively equivalent permutations of the operands of a given operation tree.
Your program will take input in the form given above, with brackets enclosing juxtaposed operators. The operands will always be lowercase letters, in alphabetical order starting from a
, and will contain a maximum of 26 letters.
Your program will output a series of permutations of the letters, without the brackets, representing all of the permutations that are associatively equivalent with the original permutation.
For example, if you are given an input of:
((ab)(cd))
Then your program will output:
abcd
abdc
bacd
badc
cdab
cdba
dcab
dcba
Your program must be accompanied by a description of its algorithm, and a proof of its asymptotic runtime with respect to the number of operands in the operation tree. The program with the lowest asymptotic runtime in this manner wins.
2With all of those parentheses everywhere, I thought I was looking at Lisp code. – Alex A. – 2015-03-17T03:14:49.700
Note: I have no idea whether this problem is NP-hard or not; I just thought of it. – Joe Z. – 2015-03-17T03:22:33.227
Why are you calling this equivalence relation associatively equivalent? Shouldn't it be commutatively equivalent? – Peter Taylor – 2015-03-17T08:16:25.690
1@JoeZ. The output size can be O(2^input_size) e.g. with a full binary tree. I'm not sure if that proves NP-hardness but it proves O(2^input_size) running time. – randomra – 2015-03-17T09:07:03.217
@PeterTaylor Because each set of these permutations forms an equivalence class of operand permutations that are equivalent without associations being universal. – Joe Z. – 2015-03-17T17:49:29.777
@randomra Maybe I should have made the problem about printing out the equivalence classes instead. – Joe Z. – 2015-03-17T17:49:43.730