3

I am attempting to create a macro that on input string (where n is the length of string) will create an array that would manually have been given by

\begin{array}{ccc... % n c's here}
    string[0] & string[1] & string[2] & ... & string[n-1]
\end{array}

For example, inputting 12345 should give

\begin{array}{ccccc}
    1 & 2 & 3 & 4 & 5
\end{array}

My best efforts have resulted in the following attempt

\documentclass{article}
\usepackage{xstring, etoolbox, pgffor}

\newcommand{\cycle}[1]{%
    \def\mystring{{#1}}
    \StrLen{\mystring}[\mystringlen]
    \def\columns{c}
    \def\content{\empty}
    \foreach \x in {0,...,\mystringlen - 1} {%
        \appto\columns{c}
        \appto\content{\StrMid{\mystring}{\x}{\x + 1} \& }
    }
    \appto\content{\StrMid{\mystring}{\mystringlen - 1}{\mystringlen}}

    \begin{array}{\columns} \content \end{array}
}

\begin{document}
$\cycle{12345}$
\end{document}

as well a host of errors. I am inexperienced with this depth of LaTeX so if anyone could tell me what is wrong with this particular example, a better way of doing this and/or the relevant sources I should look at, I would be very grateful. Thanks in advance.

4
\documentclass{article}

\makeatletter
\def\cycle#1{\xcycle{}{\@gobble}#1\relax}
\def\xcycle#1#2#3{%
\ifx\relax#3%
\begin{array}{#1}#2\end{array}%
\expandafter\@gobble
\else
\expandafter\@firstofone
\fi
{\xcycle{#1c}{#2&#3}}}
\makeatother

\begin{document}
$\cycle{12345}$
\end{document}

enter image description here

Or with egreg's extended requirements:

enter image description here

\documentclass{article}

\makeatletter
\def\cycle#1{\xcycle{}{\@gobble}#1\relax}
\def\xcycle#1#2#3{%
\ifx\relax#3%
\begin{array}{@(#1@)}#2\end{array}%
\expandafter\@gobble
\else
\expandafter\@firstofone
\fi
{\xcycle{#1c}{#2&#3}}}

\def\permutation#1{\xpermutation{}{\@gobble}#1\relax}
\def\xpermutation#1#2#3{%
\ifx\relax#3%
\begin{array}{@(#1@)}#2\end{array}%
\expandafter\@gobbletwo
\else
\ifx;#3%
\expandafter\expandafter\expandafter\@secondoftwo
\else
\expandafter\expandafter\expandafter\@firstoftwo
\fi\fi
{\xpermutation{#1c}{#2&#3}}{\xpermutation{#1@{}c@{}}{#2&)(}}%
}


\makeatother

\begin{document}
$\cycle{12345}$

$\permutation{12;34;567}$

\end{document}
  • Predictable weird macro glueing ;-) – user31729 Feb 28 '17 at 22:28
  • Thank you! I will now do my best to understand what this says... – user515914 Feb 28 '17 at 23:10
4

I suggest an approach based on expl3 and xparse:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\cycle}{m}
 {
  % split at "nothing"
  \seq_set_split:Nnn \l_egreg_cycle_seq { } { #1 }
  % the sequence length can be used to set the number of columns
  \begin{array}{* { \seq_count:N \l_egreg_cycle_seq } { c } }
  % use the sequence
  \seq_use:Nn \l_egreg_cycle_seq { & }
  \end{array}
}
\seq_new:N \l_egreg_cycle_seq
\ExplSyntaxOff

\begin{document}

X$\cycle{12345}$X

\end{document}

enter image description here

You can easily improve this to print permutations as disjoint cycles with a comfortable syntax:

\documentclass{article}
\usepackage{xparse}
\usepackage{amsmath}

\ExplSyntaxOn
\NewDocumentCommand{\cycle}{m}
 {
  \egreg_cycle:n { #1 }
 }
\NewDocumentCommand{\permutation}{m}
 {
  \egreg_permutation:n { #1 }
 }

\seq_new:N \l_egreg_permutation_seq
\seq_new:N \l_egreg_cycle_seq

\cs_new_protected:Nn \egreg_permutation:n
 {
  % split the input at semicolons
  \seq_set_split:Nnn \l_egreg_permutation_seq { ; } { #1 }
  % map the obtained sequence passing each item to \egreg_cycle:n
  \seq_map_inline:Nn \l_egreg_permutation_seq
   {
    \egreg_cycle:n { ##1 }
   }
 }
\cs_new_protected:Nn \egreg_cycle:n 
 {
  % split at "nothing"
  \seq_set_split:Nnn \l_egreg_cycle_seq { } { #1 }
  % use the sequence; no array needed, just spacing in the middle
  (\seq_use:Nn \l_egreg_cycle_seq { \mspace{6mu} })
 }

\ExplSyntaxOff

\begin{document}

$\cycle{12345}$

$\permutation{12;34;567}$

\end{document}

enter image description here

  • Predictable expl3 ;-) – user31729 Feb 28 '17 at 22:28
  • Very impressive answer but also very complicated. – user515914 Feb 28 '17 at 23:11
  • @user515914 It just takes some practice with the new programming style. No fancy \expandafter at all and very natural modularity. – egreg Feb 28 '17 at 23:12

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.