Mark Wibrow | 6 May 14:55 2009

Re: Random permutation of a list

Hi,

Actually you can use them in the list, you just can't use them as node
names (which my example relied on):

\documentclass{article}
\usepackage{tikz}

\begin{document}

\makeatletter
\def\pgfmathdeclarelist#1#2{%
	\def\pgfmath <at> list <at> name{#1}%
	\c <at> pgfmath <at> counta=0%
	\pgfmath <at> declarelistlist#2{\pgfmath <at> stop}%
}%
\def\pgfmath <at> declarelistlist#1{%
	\ifx#1\pgfmath <at> stop%
		\expandafter\edef\csname pgfmath <at> list <at> \pgfmath <at> list <at> name
 <at> length\endcsname{\the\c <at> pgfmath <at> counta}%
	\else%
		\advance\c <at> pgfmath <at> counta by1\relax%
		\pgfutil <at> namedef{pgfmath <at> list <at> \pgfmath <at> list <at> name  <at> \the\c <at> pgfmath <at> counta}{#1}%
		\expandafter\pgfmath <at> declarelistlist%
	\fi%
}

\def\pgfmathgetlistitem#1#2#3{\expandafter\let\expandafter#1\expandafter=\csname
pgfmath <at> list <at> #2 <at> #3\endcsname}

\def\pgfmathsetlistitem#1#2#3{%
	\pgfutil <at> namedef{pgfmath <at> list <at> #1 <at> #2}{#3}%
}

\def\pgfmathgetlistlength#1#2{%
	\expandafter\let\expandafter#1\expandafter=\csname
pgfmath <at> list <at> #2 <at> length\endcsname%
}

\def\pgfmathknuthshuffle#1{%
	\pgfmathgetlistlength\pgfmath <at> len{#1}%
	\pgfmathloop%
	\ifnum\pgfmathcounter>\pgfmath <at> len%
	\else%
		\pgfmathrandominteger\pgfmath <at> temp{1}{\pgfmath <at> len}%
		\pgfmathgetlistitem\pgfmath <at>  <at> temp{#1}{\pgfmathcounter}%
		\pgfmathgetlistitem\pgfmath <at>  <at>  <at> temp{#1}{\pgfmath <at> temp}%
		\def\pgfmath <at> marshal{\pgfmathsetlistitem{#1}}%
		\expandafter\pgfmath <at> marshal\expandafter{\expandafter\pgfmath <at> temp\expandafter}\expandafter{\pgfmath <at>  <at> temp}%
		\expandafter\pgfmath <at> marshal\expandafter{\expandafter\pgfmathcounter\expandafter}\expandafter{\pgfmath <at>  <at>  <at> temp}%
	\repeatpgfmathloop%
}

\makeatother

\pgfmathdeclarelist{mylist}{{A}{\Huge B}{C}{lots of text
}{E}{F}{$\frac{2}{7}$}{H}{I}{J}{K}{L}{$\sqrt{2}$}}
\pgfmathgetlistlength{\l}{mylist}

\foreach \i in {1,...,\l}{
	\pgfmathgetlistitem{\x}{mylist}{\i}
	\typeout{mylist[\i]=\x}
}

\typeout{Shuffling}

\pgfmathknuthshuffle{mylist}

\foreach \i in {1,...,\l}{
	\pgfmathgetlistitem{\x}{mylist}{\i}
	\typeout{mylist[\i]=\x}
}

\end{document}

It's  possible to define safe labels (ie aliases) for list items and
then sort the labels, and recall the items according to their labels.
A bit fiddley though.

Mark

2009/5/6 Matthew Leingang <leingang <at> courant.nyu.edu>:
> Dear Mark,
>
> [Hope this isn't too off topic.  Is there a pgfmath-users list?]
>
> Thanks for helping me clean that up.  You're right; I should just use a
> separate class for lists.
>
> Your implementation has a flaw that mine also had.  If I replace the list
> declaration with
>
>
> \pgfmathdeclarelist{mylist}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}{$\sqrt{2}$}}
>
> I get
>
>   ! Argument of \XC <at> definec <at> lor has an extra }.
>   <inserted text>
>                   \par
>   l.59 }
>
> Or if I change it to
>
>
> \pgfmathdeclarelist{mylist}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}{{$\frac{A}{B}$}}}
>
> I get
>
>   ! Missing \endcsname inserted.
>   <to be read again>
>                      \begingroup
>   l.59 }
>
> With my implementation I could use \frac but not \sqrt.
>
> I'm guessing it's a moving-arguments issue, but sprinkling \protect's in
> various places didn't have any effect.  For my implementation, I was able to
> workaround by saving the input into a box and inputing the box to the list,
> as in:
>
>   \newsavebox{\mybox}\savebox{\mybox}{$\frac{A}{B}$}
>
> \pgfmathdeclarelist{mylist}{{A}{B}{C}{D}{E}{F}{G}{H}{I}{J}{K}{L}{\usebox{\mybox}}}
>
> But for yours, again I get the "Missing \endcsname inserted" error.
>
> I need to have math in my lists (these are multiple choices on an exam), so
> I will look at our two code samples and see if I can merge them.
>
> --Matt
>
>
> On May 6, 2009, at 7:19 AM, Mark Wibrow wrote:
>
>> Hi,
>>
>> I wouldn't try to use the random list stuff. Just implement a
>> different list structure and access it using random integers. The
>> following demonstrates the sort of thing that could do it:
>>
>> [...]
>>
>> 2009/5/4 Matthew Leingang <leingang <at> courant.nyu.edu>:
>>>
>>> Hi,
>>>
>>> I'm just getting into the pgfmath package more.  Good stuff!
>>>
>>> I'm writing an exam and would like to randomly permute the order of
>>> multiple-choice items.  I was thinking of using the
>>> \pgfmathdeclarerandomlist command and then writing something to do a
>>> Knuth shuffle: for each i from 1 to n, choose a random number j from 1
>>> to n, then swap position i and j.
>>>
>>> Before I get too deep, has anyone done this or something like this
>>> before?
>>>
>>> TIA,
>>> Matt
>
> --
> Matthew Leingang
> Clinical Associate Professor of Mathematics
> leingang <at> courant.nyu.edu
>
>
>
>

------------------------------------------------------------------------------
The NEW KODAK i700 Series Scanners deliver under ANY circumstances! Your
production scanning environment may not be a perfect world - but thanks to
Kodak, there's a perfect scanner to get the job done! With the NEW KODAK i700
Series Scanner you'll get full speed at 300 dpi even with all image 
processing features enabled. http://p.sf.net/sfu/kodak-com

Gmane