# Programmatically Illustrating an Expansion Permutation

Based on the discussion over here, I drew this:
With this code:

\documentclass[tikz,border=3.14mm]{standalone}

\usepackage{tikz}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
\pgfsetlayers{background,main,foreground}

\usetikzlibrary{shapes,arrows,arrows.meta}

\tikzset{cross line/.style={>=Stealth,shorten >=5pt,shorten <=5pt, preaction={>=Stealth, draw=white, shorten >=5pt, shorten
<=5pt, line width=1.6pt}}}
%\tikzstyle{bullet} = [draw, circle,fill=cyan!20, minimum height=2.5em, text centered]

\begin{document}

\begin{tikzpicture}[pics/perms/.style={code={
\foreach \X [count=\Y] in {#1} {
\begin{pgfonlayer}{foreground}
\node[draw,bullet,] (T\Y) at (\Y,5) {\ifnum\Y<10 0\fi\Y};
\node[draw,bullet] (B\the\numexpr\X) at (\Y,-5) {\ifnum\Y<10 0\fi\Y};
\end{pgfonlayer}
}
\foreach \X [count=\Y] in {#1} {
\draw[->,>=Stealth,shorten <=-0.35pt] (T\Y.south) -> (B\Y.north);
\draw[cross line] (T\Y.south) -> (B\Y.north);
}
}},bullet/.style={circle,fill=blue!20,line width=.4pt,text=black,text width={width("33")},align=center},
scale=0.5,transform shape]

\pic{perms={3,2,1}};

\end{tikzpicture}
\end{document}


My question is: What's an elegant way to do the same thing with a permutation where some numbers are mapped more than once. If they're all mapped twice, it's fine you can just do:

\pic{perms={3,1,2}};
\pic{perms={2,3,1}};


But you can't map one twice, unless they're all mapped twice. For instance, this will show an error:

\pic{perms={3,1,2}};
\pic{perms={2, , }};


And you can't map something like 1 to 48 unless there are at least 48 numbers in the list. Here's an example of an expansion permutation from Wikipedia:

This problem is in a way simpler than the original one, at least if you know that there is an undocumented math function dim in pgfmathfunctions.misc.code.tex. This allows one to make it possible to add lists instead of single items for those cases in which one number should get mapped to multiple targets. dim can then be used to decide whether this is a single item or a list.

\documentclass[tikz,border=3.14mm]{standalone}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
\pgfsetlayers{background,main,foreground}

\usetikzlibrary{arrows.meta}

\tikzset{cross line/.style={>=Stealth,shorten >=5pt,shorten <=5pt, preaction={>=Stealth, draw=white, shorten >=5pt, shorten
<=5pt, line width=1.6pt}}}
\begin{document}

\begin{tikzpicture}[pics/perms/.style={code={
\foreach \X [count=\Y] in {#1}
{\pgfmathtruncatemacro{\mydim}{dim(\X)}
\node[draw,bullet] (T\Y) at (\Y,5) {\ifnum\Y<10 0\fi\Y};
\ifnum\mydim=1
\begin{pgfonlayer}{foreground}
\node[draw,bullet] (B\the\numexpr\X) at (\X,-5) {\ifnum\X<10 0\fi\X};
\end{pgfonlayer}
\draw[->,>=Stealth,shorten <=-0.35pt] (T\Y.south) -- (B\X.north);
\draw[cross line] (T\Y.south) -- (B\X.north);
\else
\foreach \Z in \X
{\begin{pgfonlayer}{foreground}
\node[draw,bullet] (B\the\numexpr\Z) at (\Z,-5) {\ifnum\Z<10 0\fi\Z};
\end{pgfonlayer}
\draw[->,>=Stealth,shorten <=-0.35pt] (T\Y.south) -- (B\Z.north);
\draw[cross line] (T\Y.south) -- (B\Z.north);
}
\fi}
}},bullet/.style={circle,fill=blue!20,line width=.4pt,text=black,text width={width("33")},align=center},
scale=0.5,transform shape]

\pic{perms={3,5,{1,4},{2,6}}};
\end{tikzpicture}
\end{document}