# How to generate all possible functions combinations

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}]]

• Compose @@@ Replace[Permutations@{f1, f2, f3}, {fp__, fl_} :> {fp, fl[a]}, {1}] – ciao Jun 14 at 1:06

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}

• 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. – anhnha Jun 14 at 1:58
• How would you implement the example #[5]&[f1]? The problem above is solved but I want to know a general solution for any function. – anhnha Jun 14 at 3:01
• or this #3[#2[#1[5]]] &[g,h,k] to make g[h[[k[5]]] – anhnha Jun 14 at 3:02
• Compose[##, 5] &[g, h, k] or Composition[##][5] &[g, h, k]? – kglr Jun 14 at 3:28
• what if I have a main function with arguments g, h, k and inside this main function I do various things? – anhnha Jun 14 at 3:32
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]]]}

• It works but just an additional question. How would you write it as passing function names to a function? – anhnha Jun 14 at 1:18
• Very elegant (+1). – David G. Stork Jun 14 at 3:54
• @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. – Artes Jun 16 at 0:47