我正在尝试制作一些基于随机数生成的数学公式表。我还有很多东西要学……但我认为应该从这里开始:使用随机数让 LaTeX 为我生成一串公式。
现在,基本的想法是:我首先设置\pgfmathsetmacro{\A}{random(1,4)}
为\A
1、2、3或4。
- 如果 \A=1,那么我希望出现 1+2=3。
- 如果 \A=2,那么我希望出现 2+1=3。
- 如果 \A=3,那么我希望出现 3=2+1。
- 如果 \A=4,那么我希望出现 3=1+2。
这是我目前所得到的,但是嵌套\ifthen
结构看起来非常不雅致,并且当我有 100 个不同的方程式可供选择而不是仅仅 4 个时基本上无法扩展。
有什么更好的方法吗?
\documentclass{article}
\usepackage{pgf}
\usepackage{pgffor}
\usepackage{ifthen}
\pagestyle{empty}
\setlength{\parindent}{0pt}
% THE FOUR EQUATIONS
% 1. 1+2=3
% 2. 2+1=3
% 3. 3=2+1
% 4. 3=1+2
\pgfmathsetseed{\number\pdfrandomseed}
\newcommand{\InitVariables}
{\pgfmathsetmacro{\A}{random(1,4)}}
\newcommand*{\onefact}
{
\InitVariables
\ifthenelse
{\equal{\A}{1}}{1+2=3}
{
\ifthenelse{\equal{\A}{2}}{3=2+1}
{
\ifthenelse{\equal{\A}{3}}{3=2+1}{3=1+2}
}
}
}
\newcommand{\myequations}[1]
{
\foreach \x in {1,...,#1}
{\onefact\\}
}
\begin{document}
\myequations{10}
\end{document}
答案1
如果有 100 种不同的情况,那么你的代码逻辑在某些时候是错误的。但如果情况不太多,你可以这样做\ifcase
\documentclass{article}
\usepackage{pgfmath}
\pgfmathsetseed{\number\pdfrandomseed}
\pgfmathtruncatemacro{\A}{random(1,4)}
\begin{document}
\ifcase\A\relax%
\or 1+2=3% Because \A starts from 1
\or 2+1=3%
\or 3=2+1%
\or 3=1+2%
\fi
\end{document}
答案2
luatex 的理想用例:
\documentclass[margin=1mm, varwidth=true]{standalone}
\usepackage{luacode}
\begin{luacode}
userdata = userdata or {}
local questions = {
"1 + 2 = 3" ,
"2 + 1 = 3" ,
"3 = 2 + 1" ,
"3 = 1 + 2" ,
}
function userdata.fact()
local A = math.random(#questions)
tex.print(questions[A])
end
\end{luacode}
\newcommand\Fact{\luadirect{userdata.fact()}}
\begin{document}
\begin{itemize}
\item $\Fact$
\item $\Fact$
\item $\Fact$
\item $\Fact$
\item $\Fact$
\end{itemize}
\end{document}
这使
答案3
我认为定义一个选项数组很容易,因此您可以根据需要定义或重新定义它们,而不必在嵌套结构中一起定义它们。
\documentclass{article}
\usepackage{pgffor}
\usepackage{ifthen}
\pagestyle{empty}
\setlength{\parindent}{0pt}
% THE FOUR EQUATIONS
% 1. 1+2=3
% 2. 2+1=3
% 3. 3=2+1
% 4. 3=1+2
\def\defchoice#1#2{\expandafter\def\csname X-#1\endcsname{#2}}
\defchoice{1}{$1+2=3$}
\defchoice{2}{$2+1=3$}
\defchoice{3}{$3=2+1$}
\defchoice{4}{$3=1+2$}
\pgfmathsetseed{\number\pdfrandomseed}
\newcommand{\InitVariables}
{\pgfmathsetmacro{\A}{random(1,4)}}
\newcommand*{\onefact}
{%%%%%%%%%% dont forget % at end of line
\InitVariables
\csname X-\A\endcsname}
\newcommand{\myequations}[1]
{%
\foreach \x in {1,...,#1}
{\onefact\par}% don't end a paragraph with \\
}
\begin{document}
\myequations{10}
\end{document}
答案4
可扩展意味着“良好的界面”。我们定义了一组可能的结果
\defineset{<name>}{<a>,<b>,...}
然后\printfromset{<name>}
随机选择其中一个结果;随机数将根据与特定集合相关的可能结果的数量计算得出。
\documentclass{article}
\usepackage{xparse}
\input{random} % for random numbers
\randomi=\pdfrandomseed % initialize the seed
\ExplSyntaxOn
\cs_new_eq:NN \wcla_get_random:Nnn \setrannum
\int_new:N \l_wcla_random_int
\NewDocumentCommand{\defineset}{mm}
{
\tl_new:c { g_wcla_set_#1_tl }
\int_zero:N \l_tmpa_int
\clist_map_inline:nn { #2 }
{
\int_incr:N \l_tmpa_int
\tl_gput_right:cx { g_wcla_set_#1_tl }
{
{ \int_to_arabic:n { \l_tmpa_int } }
{ \exp_not:n { ##1 } }
}
}
}
\NewDocumentCommand{\printfromset}{m}
{
\wcla_get_random:Nnn \l_wcla_random_int
{ 1 }
{ \int_eval:n { \tl_count:c { g_wcla_set_#1_tl } /2 } }
\int_case:nv { \l_wcla_random_int } { g_wcla_set_#1_tl }
}
\cs_generate_variant:Nn \int_case:nn { nv }
\ExplSyntaxOff
\defineset{equations}{
$1+2=3$,
$2+1=3$,
$3=2+1$,
$3=1+2$
}
\defineset{letters}{A,B,C,D,E,F,G,H,I}
\begin{document}
\printfromset{equations}
\printfromset{equations}
\printfromset{letters}
\printfromset{letters}
\printfromset{letters}
\printfromset{letters}
\printfromset{letters}
\printfromset{letters}
\printfromset{letters}
\printfromset{letters}
\printfromset{letters}
\printfromset{letters}
\end{document}
该\defineset
宏分配一个标记列表变量,然后按以下格式填充
{1}{<a>}{2}{<b>}...
\int_case:nn
如果我们使用变体,那么这对于 来说是很好的\int_case:nv
。请注意,项目数是结果数的两倍。
该宏\printfromset
会生成一个介于 1 和标记列表变量长度的一半之间的随机数(我们将其除以 2)。
以下是可能的输出
请注意random.tex
,这是 Donald Arsenau 编写的一组宏。语法是,\setrannum<counter>{<low>}{<high>}
它将<counter>
整数<low>
和之间的随机数存储在中<high>
(包括极值)。种子存储在计数器中\randomi
。