0

I want to random some items in an exercise and be able to display the corresponding solutions in the same order.

With xsim package such lists are in two different places so I thought about a first list to initialize a seed and the second list to use that seed.

I let you this M(N)WE adapted from this answer.

enter image description here

\documentclass{article}

\ExplSyntaxOn

\seq_new:N \l_randomlist_seq \int_new:N \l_random_items_int \NewDocumentEnvironment{randomlist}{ o +b } { % use a regular expression to split the environment % around the \item commands \regex_split:nnN { \s\c{item}\s } { #2 } \l_randomlist_seq \seq_pop_left:NN \l_randomlist_seq \l_items_tl % pop empty first item \seq_if_empty:NF \l_randomlist_seq { \seq_shuffle:N \l_randomlist_seq %% randonly shuffle items % the number of items to print is given by the optional #1 % defaulting to the full list of items \IfNoValueTF{#1}{ \int_set:Nn \l_random_items_int { \seq_count:N \l_randomlist_seq} }{ \int_set:Nn \l_random_items_int { #1 } } % finally, insert the enumerate environment \begin{enumerate} \int_do_while:nNnn \l_random_items_int > 0 { \seq_pop:NN \l_randomlist_seq \l_tmpa_tl \item \tl_use:N \l_tmpa_tl \int_decr:N \l_random_items_int% one less item to go } \end{enumerate} } }{} \ExplSyntaxOff

\begin{document} This prints four items, it's the exercise \begin{randomlist}[4] %%Generate seed \item A \item B \item C \item D \item E \end{randomlist}

This prints four items it's the solutions of the 
\begin{randomlist}[4]   %%Set seed to match the exercise seed.
    \item soltn A
    \item Soltn B
    \item Soltn C
    \item Soltn D
    \item Soltn E
\end{randomlist}

This prints all items

\begin{randomlist} \item soltn A \item Soltn B \item Soltn C \item Soltn D \item Soltn E \end{randomlist} \end{document}

Addendum :

I've tried to set the seed with \sys_gset_rand_seed the lists are now fixed but don't match each other. i.e. the elements of the exercise part are not in the same order than the solution part with same number of elements.

\documentclass{article}

\ExplSyntaxOn

\seq_new:N \l_randomlist_seq \int_new:N \l_random_items_int \sys_gset_rand_seed:n {354} %%% Despite the seed was set, the lists don't match. \NewDocumentEnvironment{randomlist}{ o +b } { % use a regular expression to split the environment % around the \item commands \seq_set_split:Nnn \l_randomlist_seq { \item } {#2} \seq_pop_left:NN \l_randomlist_seq \l_items_tl % pop empty first item \seq_if_empty:NF \l_randomlist_seq { \seq_shuffle:N \l_randomlist_seq %% randonly shuffle items % the number of items to print is given by the optional #1 % defaulting to the full list of items \IfNoValueTF{#1}{ \int_set:Nn \l_random_items_int { \seq_count:N \l_randomlist_seq} }{ \int_set:Nn \l_random_items_int { #1 } } % finally, insert the enumerate environment \begin{enumerate} \int_do_while:nNnn \l_random_items_int > 0 { \seq_pop:NN \l_randomlist_seq \l_tmpa_tl \item \tl_use:N \l_tmpa_tl \int_decr:N \l_random_items_int% one less item to go } \end{enumerate} } }{} \ExplSyntaxOff

\begin{document} This prints four items, it's the exercise \begin{randomlist}[4] %%Generate seed \item A \item B \item C \item D \item E \end{randomlist}

This prints four items it's the solutions of the 
\begin{randomlist}[4]   %%Set seed to match the exercise seed.
    \item Soltn A
    \item Soltn B
    \item Soltn C
    \item Soltn D
    \item Soltn E
\end{randomlist}

This prints all items in a different order than the two previous one
\begin{randomlist}
    \item Soltn A
    \item Soltn B
    \item Soltn C
    \item Soltn D
    \item Soltn E
\end{randomlist}

\end{document}

Piroooh
  • 1,197
  • Don't split with \regex_split:nnN here, you just want to split at \item, use \seq_set_split:Nnn \l_randomlist_seq { \item } {#2} instead (\seq_set_split:Nnn will remove the surrounding spaces for you). – Skillmon Jun 16 '23 at 09:39
  • To set the seed of the RNG use \sys_gset_rand_seed:n, to get the current seed use \sys_rand_seed: – Skillmon Jun 16 '23 at 09:41
  • Why don't you use a program, that was made for this, including solved problems with uniformity of distribution : R ? – MS-SPO Jun 16 '23 at 09:42
  • You might calculate the seed from the list contents, though expl3 doesn't have the required function built in to get the hash of a token list. But you could write your environment contents into a temporary file and use \file_mdfive_hash:n or \file_get_mdfive_hash:nN to get that file's hash, then set the seed dependent on it. – Skillmon Jun 16 '23 at 09:45
  • @Skillmon \str_mdfive_hash:n? – Joseph Wright Jun 16 '23 at 10:34
  • @JosephWright ohh, I searched the l3tl module... My bad! :) – Skillmon Jun 16 '23 at 16:43
  • @MS-SPO I like to keep things in LaTeX for coherence + I don't know R + I've already all my exercises compatible with LaTeX atm. I'm only looking for a way to random some (1 of 20) exercises. – Piroooh Jun 26 '23 at 09:18
  • @Skillmon I've tested but can't achieved what I'm expecting. With \sys_gset_rand_seed:n the lists are fixed but are not the same. See edited question – Piroooh Jun 26 '23 at 09:19
  • @Piroooh, understand. Which exam-package do you use (e.g. link to an earlier question you posted)? May be it's time for R? E.g. > sample(1:20,5,replace=F) yields 5 random samples [1] 1 4 13 7 11, which you can reuse with Latex ... – MS-SPO Jun 26 '23 at 09:42

0 Answers0