3

Based on the discussion over here, I drew this: enter image description here
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}};

enter image description here
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:
enter image description here

3

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}

enter image description here

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.