It is common for me to see if a permutation of 1,2,...,n, avoids some fixed permutation pattern. For example, the permutation [1,4,2,3,5] contains the pattern 1,3,2, as the elements [1,4,3] appear in the same relative order. For example, a function which checks if the input permutation contains the pattern 213 can be coded easily as this:
Is213AvoidingQ[p_List] := !MatchQ[p, {___, a_, ___, b_, ___, c_, ___} /; c > a > b];
Now, given a permutation pi, I want to create a function, which returns true, precisely when the input avoids pi. The idea I have is to generalize the above code, and I got the following:
IsPermutationAvoidingFunction[pi_List] :=
Module[{getVar, getBlankVar, ff, n, c, var, pattern, cond},
getVar[i_] := ToExpression@StringJoin["a", ToString@i];
getBlankVar[i_] := ToExpression@StringJoin["a", ToString@i, "_"];
n = Max@pi;
var = Table[getBlankVar[i], {i, n}];
pattern = Evaluate[Flatten[{___, Riffle[var, ___], ___}]];
cond = Table[getVar[Ordering[pi][[n + 1 - i]]], {i, n}];
cond = Greater @@ cond;
cond = Condition[pattern, Evaluate@cond];
ReleaseHold[ff[{p},
! Hold[MatchQ][p, cond]
] /. ff -> Function]
];
Now, IsPermutationAvoidingFunction[{2,1,3}]
and Is213AvoidingQ
do the same thing, great!
But can the code above be made nicer? At it is now, it looks horrible.