没有共同因子的随机数对

没有共同因子的随机数对

我的目标是定义\avar\bvar使得它们是 1 到 11 之间的整数(包括 1 和 11),但没有共同的因子,并且它们永远不会相等。

我认为我编写的代码应该这样做,但有时却不能,我不知道为什么。

有没有更简单的方法来实现这一点?或者有没有简单的方法来修复我得到的代码?

\documentclass{article}


\usepackage{pgf}
\usepackage{pgffor}
\usepackage{multicol}


\pgfmathsetseed{\number\pdfrandomseed}


\newcommand{\InitVariablesDOS}
{%
 % This randomly sets \avar to be a whole number between 1 and 10.
 % I am using the list format so that when I'm not doing a MWE,
 % I can easily weight, say, 7s to come more often.
 % Let's say in our example \avar is randomly set to 6....
 \pgfmathdeclarerandomlist{avar}{{1}{2}{3}{4}{5}{6}{7}{8}{9}{10}}
 \pgfmathrandomitem{\avar}{avar}

 % If \avar=6 I want \bvar to share no common factors (other than 1) with 6.
 % So, \bvar is selected from {DOSIfSix},
 % which are whole numbers which do not have the factors 2,3, or 6.
 \pgfmathdeclarerandomlist{DOSIfOne}{{1}{2}{3}{4}{5}{6}{7}{8}{9}{10}}
 \pgfmathdeclarerandomlist{DOSIfTwo}{{1}{3}{5}{7}{9}}
 \pgfmathdeclarerandomlist{DOSIfThree}{{1}{2}{4}{5}{7}{8}{10}}
 \pgfmathdeclarerandomlist{DOSIfFour}{{1}{3}{5}{7}{9}}
 \pgfmathdeclarerandomlist{DOSIfFive}{{1}{2}{3}{4}{6}{7}{8}{9}}
 \pgfmathdeclarerandomlist{DOSIfSix}{{1}{5}{7}{11}}
 \pgfmathdeclarerandomlist{DOSIfSeven}{{1}{2}{3}{4}{5}{6}{8}{9}{10}}
 \pgfmathdeclarerandomlist{DOSIfEight}{{1}{3}{5}{7}{9}}
 \pgfmathdeclarerandomlist{DOSIfNine}{{1}{2}{4}{5}{7}{8}{10}}
 \pgfmathdeclarerandomlist{DOSIfTen}{{1}{3}{7}{9}{11}}

 \ifcase\avar\relax% This should define \bvar so that it shares no common factors with \avar. 
  \or \pgfmathrandomitem{\bvar}{DOSIfOne}
  \or \pgfmathrandomitem{\bvar}{DOSIfTwo}
  \or \pgfmathrandomitem{\bvar}{DOSIfThree}
  \or \pgfmathrandomitem{\bvar}{DOSIfFour}
  \or \pgfmathrandomitem{\bvar}{DOSIfFive}
  \or \pgfmathrandomitem{\bvar}{DOSIfSix}  
  \or \pgfmathrandomitem{\bvar}{DOSIfSeven}
  \or \pgfmathrandomitem{\bvar}{DOSIfEight}
  \or \pgfmathrandomitem{\bvar}{DOSIfNine}
  \or \pgfmathrandomitem{\bvar}{DOSIfTen}
 \fi
 \xdef\bvar{\bvar}
}


\newcommand{\avarandbvar}
{%
\InitVariablesDOS
\(avar=\avar\)

\(bvar=\bvar\)

\vspace{0.5cm}
}

\newcommand{\manyavarandbvars}[1]{\foreach \x in {1,...,#1} {\avarandbvar}}


\pagestyle{empty}


\begin{document}
\begin{multicols}{5}
\manyavarandbvars{70}
\end{multicols}
\end{document}

在此处输入图片描述

答案1

为了进行比较,这里有一个基于 luatex 的解决方案。(我使用 ConTeXt,但将其转换为 LaTeX 也应该很简单)。为了使其更具挑战性,我通过算法生成了列表bvars

我不确定为什么有些列表到 10,而其他列表到 11。在下面的代码中,所有列表都到 10。

\startluacode
  -- Euclid's algorithm for gcd
  local gcd = function(m, n)
    while m ~= 0 do
      m, n = math.mod(n,m), m
    end
    return n
  end

  local avars = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
  local bvars = {}

  -- Generate bvars
  for i = 1, #avars do
    local a = avars[i]
    if bvars[a] == nil then
      local b = {1}
      for j = 2, 10 do
         if gcd(a, j) == 1 then
            b[#b + 1] = j
          end
      end
      bvars[a] = b
    end
  end

  local random, format = math.random, string.format

  local sampleAandB = function()
    local i = random(#avars)
    local a = avars[i]
    local j = random(#bvars[a])
    local b = bvars[a][j]

    return a, b
  end

  local avarandombvar = function()
    local a, b = sampleAandB()
    context.dontleavehmode()
    context.framed({"frame=off, align=middle"}, format("avar = %s \\crlf bvar = %s", a, b))
    context.blank{"big"}
  end

  interfaces.definecommand ("avarandombvar", {macro = avarandombvar})

\stopluacode

\starttext

\startcolumns[n=5]
\dorecurse{70}{\avarandombvar}
\stopcolumns

\stoptext

这使

在此处输入图片描述

答案2

首先解决你的问题:

您需要保留\avar以防止其发生变化。这可以\edef\avar{\avar}在之后添加来完成\pgfmathrandomitem{\avar}{avar}

建议:您可以将随机列表的声明移到前言中。这样,它们只定义一次,而不是每次都\InitVariablesDOS使用。并且您应该注释掉几行的行尾\InitVariablesDOS。否则,它们可能会产生虚假空格,具体取决于调用宏的位置。

\documentclass{article}


\usepackage{pgf}
\usepackage{pgffor}
\usepackage{multicol}


\pgfmathsetseed{\number\pdfrandomseed}
\pgfmathdeclarerandomlist{avar}{{1}{2}{3}{4}{5}{6}{7}{8}{9}{10}}
\pgfmathdeclarerandomlist{DOSIfOne}{{1}{2}{3}{4}{5}{6}{7}{8}{9}{10}}
\pgfmathdeclarerandomlist{DOSIfTwo}{{1}{3}{5}{7}{9}}
\pgfmathdeclarerandomlist{DOSIfThree}{{1}{2}{4}{5}{7}{8}{10}}
\pgfmathdeclarerandomlist{DOSIfFour}{{1}{3}{5}{7}{9}}
\pgfmathdeclarerandomlist{DOSIfFive}{{1}{2}{3}{4}{6}{7}{8}{9}}
\pgfmathdeclarerandomlist{DOSIfSix}{{1}{5}{7}{11}}
\pgfmathdeclarerandomlist{DOSIfSeven}{{1}{2}{3}{4}{5}{6}{8}{9}{10}}
\pgfmathdeclarerandomlist{DOSIfEight}{{1}{3}{5}{7}{9}}
\pgfmathdeclarerandomlist{DOSIfNine}{{1}{2}{4}{5}{7}{8}{10}}
\pgfmathdeclarerandomlist{DOSIfTen}{{1}{3}{7}{9}{11}}

\newcommand{\InitVariablesDOS}
{%
 \pgfmathrandomitem{\avar}{avar}%
 % added as workaround
 \edef\avar{\avar}%
 % to show the problem, uncomment the next line and comment out the previous one
% \(avar=\avar\)

 \ifcase\avar\relax% This should define \bvar so that it shares no common factors with \avar. 
  \or \pgfmathrandomitem{\bvar}{DOSIfOne}%
  \or \pgfmathrandomitem{\bvar}{DOSIfTwo}%
  \or \pgfmathrandomitem{\bvar}{DOSIfThree}%
  \or \pgfmathrandomitem{\bvar}{DOSIfFour}%
  \or \pgfmathrandomitem{\bvar}{DOSIfFive}%
  \or \pgfmathrandomitem{\bvar}{DOSIfSix}%
  \or \pgfmathrandomitem{\bvar}{DOSIfSeven}%
  \or \pgfmathrandomitem{\bvar}{DOSIfEight}%
  \or \pgfmathrandomitem{\bvar}{DOSIfNine}%
  \or \pgfmathrandomitem{\bvar}{DOSIfTen}%
 \fi
 \edef\bvar{\bvar}%
}


\newcommand{\avarandbvar}
{%
\InitVariablesDOS

\(avar=\avar\)

\(bvar=\bvar\)

\vspace{0.5cm}
}

\newcommand{\manyavarandbvars}[1]{\foreach \x in {1,...,#1} {\avarandbvar}}


\pagestyle{empty}


\begin{document}
\begin{multicols}{5}
\manyavarandbvars{70}
\end{multicols}
\end{document}

现在说说问题的原因:

在这种情况下,它与组和/或全局化无关\avar。问题来自pgf以及它如何用 定义宏\pgfmathrandomitem。如果后者被调用用于不同的宏,例如

\pgfmathrandomitem{\avar}{avar}
\pgfmathrandomitem{\bvar}{bvar}

第二次调用也会改变第一次的结果。因此,必须用 保留第一个结果\edef\avar{\avar}

详细信息(你可以在这里停止阅读):

该宏的简单定义如下\def(pgfmathfunctions.random.code.tex,第 241 和 242 行):

\pgfmathrandominteger{\pgfmath@randomtemp}{1}{\pgfmath@randomlistlength}%
\def#1{\csname pgfmath@randomlist@#2@\pgfmath@randomtemp\endcsname}}}

可以看出,宏的内容取决于\pgfmath@randomtemp。如果它发生变化,宏也会发生变化。每次\pgfmathrandomitem调用时都会发生这种情况,即使是对来自不同列表的不同宏执行此操作也是如此。

由于我想不出在这里使用\def而不是 的理由\edef来避免这个问题,所以我认为这是一个错误。

相关内容