4
$\begingroup$

Assume that I have 3 functions like this (total 10 functions in reality).

f1[x_] := 3 x;
f2[x_] := x^2 - 1;
f3[x_] := 2 x + 5;

Now I want to generate all possible combinations like this:

f1[f2[f3[a]]], f1[f3[f2[a]]], f2[f1[f3[a]]], f2[f3[f1[a]]], f3[
 f1[f2[a]]], f3[f2[f1[a]]]

How can I do that? I tried this but it doesn't work.

#3[#2[#1[5]]] & /@ Map[Sequence @@ &, Permutations[{f1, f2, f3}]]
$\endgroup$
1
  • 3
    $\begingroup$ Compose @@@ Replace[Permutations@{f1, f2, f3}, {fp__, fl_} :> {fp, fl[a]}, {1}] $\endgroup$ – ciao Jun 14 at 1:06
11
$\begingroup$
ClearAll[allCompositions]
allCompositions[a_] := Through @ (Permutations @* Composition)[##] @ a &;

Examples:

allCompositions[x][f1, f2, f3]
{f1[f2[f3[x]]], f1[f3[f2[x]]], f2[f1[f3[x]]], f2[f3[f1[x]]], 
 f3[f1[f2[x]]], f3[f2[f1[x]]]}
allCompositions[x] @@ {f1, f2, f3}
{f1[f2[f3[x]]], f1[f3[f2[x]]], f2[f1[f3[x]]], f2[f3[f1[x]]], 
 f3[f1[f2[x]]], f3[f2[f1[x]]]}
f1[x_] := 3 x;
f2[x_] := x^2 - 1;
f3[x_] := 2 x + 5;

allCompositions[x][f1, f2, f3] // FullSimplify
{12 (2 + x) (3 + x), 9 + 6 x^2,  4 (7 + 3 x) (8 + 3 x),
-1 + (5 + 6 x)^2, -1 + 6 x^2, 3 + 18 x^2}
allCompositions[5][f1, f2, f3]
{672, 159, 2024, 1224, 149, 453}

Alternatively,

ClearAll[allCompositions2]
allCompositions2[f__] := Through @ (Permutations@*Composition)[f] @ ## &;

allCompositions2[h1, h2, h3] @ x
{h1[h2[h3[x]]], h1[h3[h2[x]]], h2[h1[h3[x]]], h2[h3[h1[x]]], 
 h3[h1[h2[x]]], h3[h2[h1[x]]]}
allCompositions2[h1, h2][x, y, z]
{h1[h2[x, y, z]], h2[h1[x, y, z]]}
allCompositions2[f1, f2, f3] @ 5
{672, 159, 2024, 1224, 149, 453}
$\endgroup$
6
  • $\begingroup$ This is nice but how would you pass a function to the function? That would make a general solution. I tried #[5]&[f1] but it doesn't do anything. $\endgroup$ – anhnha Jun 14 at 1:58
  • $\begingroup$ How would you implement the example #[5]&[f1]? The problem above is solved but I want to know a general solution for any function. $\endgroup$ – anhnha Jun 14 at 3:01
  • $\begingroup$ or this #3[#2[#1[5]]] &[g,h,k] to make g[h[[k[5]]] $\endgroup$ – anhnha Jun 14 at 3:02
  • $\begingroup$ Compose[##, 5] &[g, h, k] or Composition[##][5] &[g, h, k]? $\endgroup$ – kglr Jun 14 at 3:28
  • $\begingroup$ what if I have a main function with arguments g, h, k and inside this main function I do various things? $\endgroup$ – anhnha Jun 14 at 3:32
10
$\begingroup$
Composition[##][x] & @@@ Permutations[{f1, f2, f3}]
{f1[f2[f3[x]]], f1[f3[f2[x]]], f2[f1[f3[x]]], 
 f2[f3[f1[x]]], f3[f1[f2[x]]], f3[f2[f1[x]]]}
$\endgroup$
3
  • $\begingroup$ It works but just an additional question. How would you write it as passing function names to a function? $\endgroup$ – anhnha Jun 14 at 1:18
  • 1
    $\begingroup$ Very elegant (+1). $\endgroup$ – David G. Stork Jun 14 at 3:54
  • $\begingroup$ @anhnha If I understand your question you should examine what ## does, i.e. look at SlotSequence. Otherwise you should explain more clearly what you mean. $\endgroup$ – Artes Jun 16 at 0:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.