如何随机化表格的条目?

如何随机化表格的条目?

考虑以下代码。这样的随机化可能吗?我有许多不同的表格,每个表格中的字母数量可能不同。但是,在每个表格中,字母始终对应于字母表的第一个字母。

在此处输入图片描述

\documentclass[english]{article}
\usepackage[T1]{fontenc}
\usepackage[latin9]{inputenc}

\makeatletter

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% LyX specific LaTeX commands.
%% Because html converters don't know tabularnewline
\providecommand{\tabularnewline}{\\}

\makeatother

\usepackage{babel}
\begin{document}
\begin{tabular}{|c|c|c|}
\hline 
\fbox{A} & 4 & \fbox{C}\tabularnewline
\hline 
2 & \fbox{B} & 3\tabularnewline
\hline 
\end{tabular}

\bigskip{}

\fbox{A} 5 \fbox{B} 6 \fbox{C} 7

\bigskip{}

I want to randomize A, B and C in different versions of this document.
For instance, one possible randomization is the following:

\bigskip{}

\begin{tabular}{|c|c|c|}
\hline 
\fbox{B} & 4 & \fbox{A}\tabularnewline
\hline 
2 & \fbox{C} & 3\tabularnewline
\hline 
\end{tabular}

\bigskip{}

\fbox{A} 7 \fbox{B} 5 \fbox{C} 6 (Please, notice that now A, B
and C correspond to 7, 5 and 6.)

\bigskip{}

\end{document}

答案1

我希望以下内容能满足您的要求。它创建一个名为的环境,randomhidetable其中tabular每个字段都\hide被字母表前 $n$ 个字符序列的随机元素替换(每个元素仅使用一次)。该表被评估两次,第一次评估计算元素数量\hide,第二次对其进行排版。您可以\hide使用环境的第二个可选参数(位于强制参数之后)更改为任意宏。

\__paul_hide_output_format:n可以通过改变 的定义(当前定义为)来定制隐藏标签的格式\fbox{#1}

您可以使用带有四个参数的宏输出隐藏的单元格\hiddencells

  1. 标签和值之间的分隔符
  2. 如果只有两个标签,则不同标签之间的分隔符
  3. 如果有两个以上的标签,则使用不同标签之间的分隔符(最后两个除外)
  4. 如果有两个以上的标签,则在最后两个标签之间添加分隔符
\documentclass[]{article}

\usepackage{xparse}
\ExplSyntaxOn
\tl_new:N \l__paul_reveal_separator_tl
\int_new:N \g__paul_hide_count_int
\seq_new:N \g__paul_hide_seq
\seq_new:N \g__paul_hidden_seq
\seq_new:N \g__paul_reveal_seq
\NewDocumentEnvironment { randomhidetable } { O{c} +m O{\hide} +b }
  {
    \group_begin:
      \int_gzero:N \g__paul_hide_count_int
      \cs_set:Npn #3 ##1 { \int_gincr:N \g__paul_hide_count_int }
      \hbox_set:Nn \l_tmpa_box { \begin { tabular } { #2 } #4 \end { tabular } }
    \group_end:
    \seq_gclear:N \g__paul_hide_seq
    \seq_gclear:N \g__paul_hidden_seq
    \int_step_inline:nn \g__paul_hide_count_int { \seq_gpush:Nn \g__paul_hide_seq { ##1 } }
    \seq_gshuffle:N \g__paul_hide_seq
    \cs_set:Npn #3 ##1
      {
        \seq_gpop:NN \g__paul_hide_seq \l_tmpa_tl
        \__paul_hide_output_format:x { \char_generate:nn { 64 + \l_tmpa_tl } { 11 } }
        \seq_gpush:Nx \g__paul_hidden_seq { { \l_tmpa_tl } { ##1 } }
      }
    \begin { tabular } [ #1 ] { #2 } #4 \end { tabular }
    \seq_gsort:Nn \g__paul_hidden_seq
      {
        \int_compare:nNnTF { \use_i:nn ##1 } > { \use_i:nn ##2 }
          { \sort_return_swapped: }
          { \sort_return_same: }
      }
    \seq_gclear:N \g__paul_reveal_seq
    \seq_map_inline:Nn \g__paul_hidden_seq
      {
        \__paul_hide_output_hidden_values:nn ##1
      }
  }
  {}
\cs_new:Npn \__paul_hide_output_hidden_values:nn #1 #2
  {
    \seq_gput_right:Nx \g__paul_reveal_seq
      {
        \exp_not:N \__paul_hide_output_format:n
          { \char_generate:nn { 64 + #1 } { 11 } }
        \exp_not:n { \l__paul_reveal_separator_tl #2 }
      }
  }
\cs_new:Npn \__paul_hide_output_format:n #1
  {
    \fbox { #1 }
  }
\cs_generate_variant:Nn \__paul_hide_output_format:n { x }
\NewDocumentCommand \hiddencells { m m m m }
  {
    \group_begin:
      \tl_set:Nn \l__paul_reveal_separator_tl { #1 }
      \seq_use:Nnnn \g__paul_reveal_seq { #2 } { #3 } { #4 }
    \group_end:
  }
\ExplSyntaxOff

\begin{document}
\makebox[2cm][l]{First call:}
\begin{randomhidetable}[b]{ccc}
  \hide{5} & 4 & \hide{7} \\
  2 & \hide{6} & 3
\end{randomhidetable}
The hidden fields were: \hiddencells{~}{, }{, }{, and }

\makebox[2cm][l]{Second call:}
\begin{randomhidetable}[t]{ccc}[\foo]
  \foo{5} & 4 & \foo{7} \\
  2 & \foo{6} & 3
\end{randomhidetable}
The hidden fields were: \hiddencells{~}{ and }{, }{, and }
\end{document}

在此处输入图片描述

编辑:environ如果您没有足够新的版本,可以使用该包作为替代版本xparseenviron调用基础环境randomhidetable*,不支持第二个可选参数。为了仍然能够设置使用的宏,\sethidemacro引入了新的宏(旧环境仍然有效):

\documentclass[]{article}

\usepackage{xparse}
\usepackage{environ}
\ExplSyntaxOn
\tl_new:N \l__paul_reveal_separator_tl
\tl_new:N \l__paul_hide_macro_name_tl
\tl_set:Nn \l__paul_hide_macro_name_tl { \hide }
\int_new:N \g__paul_hide_count_int
\seq_new:N \g__paul_hide_seq
\seq_new:N \g__paul_hidden_seq
\seq_new:N \g__paul_reveal_seq
%\NewDocumentEnvironment { randomhidetable } { O{c} +m o +b }
%  {
%    \IfValueTF { #3 }
%      { \__paul_randomhidetable_code:nnnn { #1 } { #2 } { #3 } { #4 } }
%      {
%        \__paul_randomhidetable_code:nnVn
%          { #1 } { #2 } \l__paul_hide_macro_name_tl { #4 }
%      }
%  }
%  {}
\cs_new:Npn \__paul_randomhidetable_code:nnnn #1 #2 #3 #4
  {
    \group_begin:
      \int_gzero:N \g__paul_hide_count_int
      \cs_set:Npn #3 ##1 { \int_gincr:N \g__paul_hide_count_int }
      \hbox_set:Nn \l_tmpa_box { \begin { tabular } { #2 } #4 \end { tabular } }
    \group_end:
    \seq_gclear:N \g__paul_hide_seq
    \seq_gclear:N \g__paul_hidden_seq
    \int_step_inline:nn \g__paul_hide_count_int { \seq_gpush:Nn \g__paul_hide_seq { ##1 } }
    \seq_gshuffle:N \g__paul_hide_seq
    \cs_set:Npn #3 ##1
      {
        \seq_gpop:NN \g__paul_hide_seq \l_tmpa_tl
        \__paul_hide_output_format:x { \char_generate:nn { 64 + \l_tmpa_tl } { 11 } }
        \seq_gpush:Nx \g__paul_hidden_seq { { \l_tmpa_tl } { ##1 } }
      }
    \begin { tabular } [ #1 ] { #2 } #4 \end { tabular }
    \seq_gsort:Nn \g__paul_hidden_seq
      {
        \int_compare:nNnTF { \use_i:nn ##1 } > { \use_i:nn ##2 }
          { \sort_return_swapped: }
          { \sort_return_same: }
      }
    \seq_gclear:N \g__paul_reveal_seq
    \seq_map_inline:Nn \g__paul_hidden_seq
      {
        \__paul_hide_output_hidden_values:nn ##1
      }
  }
\cs_generate_variant:Nn \__paul_randomhidetable_code:nnnn { nnVV }
\cs_generate_variant:Nn \__paul_randomhidetable_code:nnnn { nnVn }
\cs_new:Npn \__paul_hide_output_hidden_values:nn #1 #2
  {
    \seq_gput_right:Nx \g__paul_reveal_seq
      {
        \exp_not:N \__paul_hide_output_format:n
          { \char_generate:nn { 64 + #1 } { 11 } }
        \exp_not:n { \l__paul_reveal_separator_tl #2 }
      }
  }
\cs_new:Npn \__paul_hide_output_format:n #1
  {
    \fbox { #1 }
  }
\cs_generate_variant:Nn \__paul_hide_output_format:n { x }
\NewDocumentCommand \hiddencells { m m m m }
  {
    \group_begin:
      \tl_set:Nn \l__paul_reveal_separator_tl { #1 }
      \seq_use:Nnnn \g__paul_reveal_seq { #2 } { #3 } { #4 }
    \group_end:
  }
\NewDocumentCommand \sethidemacro { m }
  {
    \tl_set:Nn \l__paul_hide_macro_name_tl { #1 }
  }
\NewEnviron{randomhidetable*}[2][c]
  {
    \__paul_randomhidetable_code:nnVV
      { #1 } { #2 } \l__paul_hide_macro_name_tl \BODY
  }
\ExplSyntaxOff


\begin{document}
\makebox[2cm][l]{First call:}
\begin{randomhidetable*}[b]{ccc}
  \hide{5} & 4 & \hide{7} \\
  2 & \hide{6} & 3
\end{randomhidetable*}
The hidden fields were: \hiddencells{~}{ and }{, }{, and }

\makebox[2cm][l]{Second call:}
\begingroup
\sethidemacro{\foo}
\begin{randomhidetable*}[t]{ccc}
  \foo{5} & 4 & \foo{7} \\
  2 & \foo{6} & 3
\end{randomhidetable*}
\endgroup
The hidden fields were: \hiddencells{~}{ and }{, }{, and }
\end{document}

答案2

由于 Skillmon 的解决方案无法在我的 LaTeX 发行版上编译(Fedora Linux 仍然使用 TexLive 2018),我不得不寻找其他解决方案。我找到了以下解决方案,它使用Rvia knitr

在此处输入图片描述

\documentclass[english]{article}
\usepackage[T1]{fontenc}
\usepackage[latin9]{inputenc}
\usepackage{geometry}
\geometry{verbose,tmargin=2cm,bmargin=2cm,lmargin=2cm,rmargin=2cm}

\makeatletter

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% LyX specific LaTeX commands.
%% Because html converters don't know tabularnewline
\providecommand{\tabularnewline}{\\}

\makeatother

\usepackage{babel}
\begin{document}
<<echo=F>>=

v <- c("A","B","C")
w <- c(10,20,30)
order <- sample(1:3)
v <- v[order]
@

\noindent \begin{center}
\begin{tabular}{|c|c|c|}
\hline 
\fbox{\Sexpr{v[1]}} & 4 & \fbox{\Sexpr{v[3]}}\tabularnewline
\hline 
2 & \fbox{\Sexpr{v[2]}} & 6\tabularnewline
\hline 
\end{tabular}
\par\end{center}

This time, we have: A=\Sexpr{w[which(v == "A")]}, B=\Sexpr{w[which(v == "B")]}
e C=\Sexpr{w[which(v == "C")]}.
<<echo=F>>=

ordem <- sample(1:3)
v <- v[ordem]
@

\noindent \begin{center}
\begin{tabular}{|c|c|c|}
\hline 
\fbox{\Sexpr{v[1]}} & 4 & \fbox{\Sexpr{v[3]}}\tabularnewline
\hline 
2 & \fbox{\Sexpr{v[2]}} & 6\tabularnewline
\hline 
\end{tabular}
\par\end{center}

This time, we have: A=\Sexpr{w[which(v == "A")]}, B=\Sexpr{w[which(v == "B")]}
e C=\Sexpr{w[which(v == "C")]}.
\end{document}

相关内容