使用别名/变量作为新命令的输入

使用别名/变量作为新命令的输入

我目前正在尝试设置一个条件语句,该语句采用随机分配的整数,并根据整数是奇数还是偶数提供特定的输出。到目前为止,我已经写了这个

\documentclass[12pt]{article}
\usepackage[first=-20, last=20]{lcg}
\usepackage{tikz}
\usepackage{calculator}
\usepackage{calculus}
\usepackage{ifthen}

\newcommand{\randi}{\rand\arabic{rand}}
\newcommand{\addsub}{\pgfmathrandomitem{\choice}{choices1}\choice}
\pgfmathdeclarerandomlist{choices1}{{+}{-}}

\newcommand{\firstpower}{\chgrand[first=2, last=5] \randi}

\newcommand{\Oddleft}[1]{
  \ifodd#1
    |
  \else
    (
  \fi
}

\newcommand{\Oddright}[1]{
  \ifodd#1
    |
  \else
    )
  \fi
}

\begin{document}

\section*{Problem 1}
Provide the output of the function $f(x) = \randi 
\Oddleft{\firstpower}
x \addsub \chgrand[first=1, last=20] \randi
\Oddright{\firstpower} ^{\firstpower}$ for values of $x = \chgrand[last=-50, last=50]$
\\

\end{document}

目前,此代码的要点是,如果幂为奇数,则将表达式括在绝对值栏中,如果幂为偶数,则括在括号中。但是,命令\Oddleft不会\Oddright将我的命令解释\firstpower为数字,因此输入被视为零。我如何声明/别名一个随机数,以便可以将其用作另一个命令的输入?

答案1

您需要首先将指数保存为可以输入\Oddleft或的值\Oddright(即使使用\firstpower工作,每次使用时也会计算不同的值)。

以下是一种不同的方法expl3

\documentclass[12pt]{article}
\usepackage{xfp}

\ExplSyntaxOn
\NewDocumentCommand{\expression}{}
 {
  % a random sign, print nothing if positive
  \int_if_odd:nT { \int_rand:nn { 1 } { 2 } } { - }
  % the absolute value of the coefficient
  \int_rand:nn { 1 } { 20 }
  % compute a random exponent
  \int_set:Nn \l_tmpa_int { \int_rand:nn { 2 } { 5 } }
  % if odd exponent, use |, else (
  \int_if_odd:nTF \l_tmpa_int { | } { ( }
  % the variable
  x
  % a random sign
  \int_if_odd:nTF { \int_rand:nn { 1 } { 2 } } { - } { + }
  % the absolute value of the summand
  \int_rand:nn { 1 } { 20 }
  % if odd exponent use |, else )
  \int_if_odd:nTF \l_tmpa_int { | } { ) }
  % the exponent
  \sp { \int_use:N \l_tmpa_int }
 }

% print a row of values
\NewDocumentCommand{\randomvalues}{m}
 {
  \int_rand:nn { -50 } { 50 }
  \prg_replicate:nn { #1 - 1 } { , \int_rand:nn { -50 } { 50 } }
 }
\ExplSyntaxOff

\begin{document}

Provide the output of the function $f(x) = \expression$

Provide the output of the function $f(x) = \expression$

Provide the output of the function $f(x) = \expression$

Provide the output of the function $f(x) = \expression$

Provide the output of the function $f(x) = \expression$

Provide the output of the function $f(x) = \expression$

Provide the output of the function $f(x) = \expression$ for the values $x=\randomvalues{4}$

\end{document}

在此处输入图片描述

答案2

您可以使用

\ExplSyntaxOn
\newcommand{\firstpower}{\int_rand:nn{2}{5}}
\ExplSyntaxOff 

这是一个可扩展的数字

答案3

有几个问题需要考虑:

其中最值得注意的是:

  • 您的代码旨在在每次运行 LaTeX 时创建并输出一组随机数。
    但通常需要运行几次 LaTeX 才能使所有内容(交叉引用、目录等)匹配。
    我认为,只有当无法通过 .aux 文件从上一次运行的 LaTeX 中检索到随机数时,才创建随机数的机制是一个好主意。否则,您可能最终需要很长的编译周期,直到所有内容意外匹配:

    • 随机变量的改变会改变文档的文本。
    • 更改文档的文本可能会改变文本分页的方式。
    • 改变文本的分页方式可能会导致交叉引用和目录的页码等不匹配。
    • 交叉引用和目录的页码等不匹配需要另一次 LaTeX 运行。
    • 随着 LaTeX 运行,随机变量发生了改变。
    • 随机变量的改变会改变文档的文本。
    • ...

    在下面的示例中,引用标签从练习中使用的数字/系数写入 .aux 文件。仅当无法从 .aux 文件的引用标签中检索到练习中使用的数字时,才会随机创建它们。

  • 您可能希望防止两次创建相同的练习/函数表达式。因此,\expressionlist维护一个宏,其中包含一个非分隔参数列表,每个参数都包含练习中使用的数字/系数集。重复创建随机数,直到获得列表中尚未存在的星座。(如果您运气不好,这种情况永远不会发生。;-))

  • 您可能希望函数输出的值列表不包含两次相同的值。为此列表选择一个随机值会重复进行,直到找到一个不在列表中的值。(如果您运气不好,这种情况永远不会发生。;-))

  • 您可能希望函数输出的值列表按升序排序。

  • 带有图案的表达

答案4

这个“答案”并没有提供问题的解决方案。

正如您在问题中使用了 lcg-package 一样,让我们​​提一下 lcg 包(lcg 包,2013/08/09 (v1.3),CTAN:https://www.ctan.org/pkg/lcg) 会产生伪空间标记。

(我已经尝试通过软件包文档中提供的电子邮件地址联系软件包作者。邮件既没有被退回,也没有收到任何回复。我们生活在动荡的时代。把这些事情整理好也许是件好事。但我不想劫持/接管这个包裹,因为那可能不太礼貌。)

您可以轻松重现此现象:

\documentclass{article}
\usepackage{lcg}
\begin{document}
\noindent X\rand X

\noindent X\chgrand[first=1,last=20,quiet=y]X

\noindent X\rand X
\end{document}

\rand\chgrand诸如此类不应该产生可见的输出。

因此我期望上述最小示例的视觉输出如下所示:

XX
XX
XX

但是 X 与空格交织在一起,你会得到如下结果:

X X
X  X
XX

原因是键的定义文本quiet和宏的定义文本都\r@nd产生了虚假的空间标记。

下面我复制了这些定义并标记了<-!!!!!伪空间标记出现的位置:

84 \define@key{Init}{quiet}[y]{ <-!!!!!
85   \def\qui@t{\expandafter\firstletterr@nd #1\delimiter} <-!!!!!
86   \if \qui@t y% nothing to do
87   \else\if\qui@t Y \def\qui@t{y} <-!!!!! (2x)
88   \else\if\qui@t j \def\qui@t{y} <-!!!!! (2x)
89   \else\if\qui@t J \def\qui@t{y} <-!!!!! (2x)
90   \else\if\qui@t n \def\qui@t{n} <-!!!!! (2x)
91   \else\if\qui@t N \def\qui@t{n} <-!!!!! (2x)
92   \else
93     \PackageWarning{lcg}{Value of key <quiet> must be <y> or <n>} <-!!!!!
94     \def\qui@t{y} <-!!!!!
95   \fi\fi\fi\fi\fi\fi
96 }

173 \def\r@nd{%
174   \ifnum \cr@nd < \@ne% then ... initialize generator
175     \cr@nd = \the\time
176     \advance \cr@nd \inputlineno
177     \multiply \cr@nd \value{page} <-!!!!!
178     \advance \cr@nd \the\year
179     \multiply \cr@nd \the\month
180     \multiply \cr@nd \the\day
181     \advance \cr@nd \inputlineno
182     \if \qui@t y%
183     \else
184       \typeout{Random number generator initialized to \the\cr@nd}%
185     \fi
186     \r@nd%
187   \else % else ... generate new number
188     \@tempcnta = \cr@nd
189     \divide \@tempcnta 127773 % \@tempcnta = floor(z/q)
190     \@tempcntb = \@tempcnta % \@tempcntb = floor(z/q)
191     \multiply \@tempcnta -2836 % \@tempcnta = -r*floor(z/q)
192     \multiply \@tempcntb -127773 % \@tempcntb = -q*floor(z/q)
193     \advance \cr@nd \@tempcntb % cr@nd = z mod q
194     \multiply \cr@nd 16807 % cr@nd = a * (z mod q)
195     \advance \cr@nd \@tempcnta % cr@nd = a*z mod m
196     \ifnum \cr@nd < \z@%
197       \advance \cr@nd 2147483647 % cr@nd = (a*z mod m) > 0
198     \fi
199     \global\cr@nd=\cr@nd % persist the change outside current scope
200   \fi
201 }% end of \r@nd

我建议进行以下更改:

\define@key{Init}{quiet}[y]{%
  \def\qui@t{\expandafter\firstletterr@nd #1\delimiter}%
  \if \qui@t y% nothing to do
  \else\if\qui@t Y\def\qui@t{y}%
  \else\if\qui@t j\def\qui@t{y}%
  \else\if\qui@t J\def\qui@t{y}%
  \else\if\qui@t n\def\qui@t{n}%
  \else\if\qui@t N\def\qui@t{n}%
  \else
    \PackageWarning{lcg}{Value of key <quiet> must be <y> or <n>}%
    \def\qui@t{y}%
  \fi\fi\fi\fi\fi\fi
}

 

\def\rand{%
  \r@nd%
  \@tempcnta
  \@tempcntb
  \@tempcnta = \f@rst
  \@tempcntb = \l@st
  \multiply \@tempcnta \m@ne
  \advance \@tempcntb \@tempcnta
  \advance \@tempcntb \@ne %l@st-f@rst+1
  \@tempcnta = 2147483647
  \divide \@tempcnta \@tempcntb
  \multiply \@tempcnta \@tempcntb
  \ifnum \cr@nd > \@tempcnta\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
  {\rand}%
  {%
    \setcounter{\r@ndcountername}{\cr@nd}%
    \@tempcnta = \cr@nd
    \divide \@tempcnta \@tempcntb
    \multiply \@tempcnta \@tempcntb
    \multiply \@tempcnta \m@ne
    \addtocounter{\r@ndcountername}{\@tempcnta}%
    \addtocounter{\r@ndcountername}{\f@rst}%
  }%
}% end of \rand

 

\def\r@nd{%
  \ifnum \cr@nd < \@ne\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
  {% then ... initialize generator
    \cr@nd = \the\time
    \advance \cr@nd \inputlineno
    \multiply \cr@nd \value{page}%%%%%%%
    \advance \cr@nd \the\year
    \multiply \cr@nd \the\month
    \multiply \cr@nd \the\day
    \advance \cr@nd \inputlineno
    \if \qui@t y%
    \else
      \typeout{Random number generator initialized to \the\cr@nd}%
    \fi
    \r@nd%
  }{% else ... generate new number
    \@tempcnta = \cr@nd
    \divide \@tempcnta 127773 % \@tempcnta = floor(z/q)
    \@tempcntb = \@tempcnta % \@tempcntb = floor(z/q)
    \multiply \@tempcnta -2836 % \@tempcnta = -r*floor(z/q)
    \multiply \@tempcntb -127773 % \@tempcntb = -q*floor(z/q)
    \advance \cr@nd \@tempcntb % cr@nd = z mod q
    \multiply \cr@nd 16807 % cr@nd = a * (z mod q)
    \advance \cr@nd \@tempcnta % cr@nd = a*z mod m
    \ifnum \cr@nd < \z@%
      \advance \cr@nd 2147483647 % cr@nd = (a*z mod m) > 0
    \fi
    \global\cr@nd=\cr@nd % persist the change outside current scope
  }%
}% end of \r@nd

相关内容