# Making a macro that makes input string the contents of a row array

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.

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


Or with egreg's extended requirements:

\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

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}


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}


• 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