1

I'm having a really hard time understanding why the following \ifthenelse check will always result false.

I already used strings and commands in my conditionals and I know that they work. In this particular case though something goes wrong.

To simplify the analysis of this code I'll explain how it should work.

Its objective is to give a random value between 1 and 9 to the counters a and b. Such output is written on the document in the shape of "a=x b=y axby", where x and y are their random values. Then, if the output of a\thea{}b\theb{} is one of a series of given options (a1b1, a2b3, a3b7...) pdflatex will print "TRUE" at the side of the previous line. Otherwise, if such condition is false, it will print "FALSE" instead. Such code is repeated 100 times.

The Random command works pretty well and it will give to the counter #3 a value between #1 and #2. It's built in such a way that it will change seed every time it's called, but the initial seed is given by the document itself. Since it will always create a new seed using the previous seed, what happens is that if you'll use this code you will always have the same output.

So you'll notice that it will always print "FALSE" even though there are some lines on which it should print "TRUE". For example, the fourth one is "a=6 b=1 a6b1". Though, every line will end with FALSE.

I used \ttfamily so it's easier to read.

So here's the MWE.

\documentclass{article}

\usepackage{xifthen}
\usepackage{lcg}
\usepackage{pgffor}

\newcounter{a}
\newcounter{b}
\newcounter{SEED}

\newcommand{\Random}[3]{%
    \reinitrand[last=2147483647, seed=\value{SEED}]%
    \rand%
    \setcounter{SEED}{\therand}%
    \reinitrand[first=#1, last=#2, seed=\value{SEED}]%
    \rand%
    \setcounter{#3}{\value{rand}}%
}

\begin{document}
    \ttfamily
    \setcounter{SEED}{10}
    \foreach \num in {1,...,100} {%
        \Random{1}{9}{a}%
        \Random{1}{9}{b}%
        a=\thea\ b=\theb\ a\thea{}b\theb{} %
        \ifthenelse{%
            \equal{a\thea{}b\theb{}}{a1b1} \OR %
            \equal{a\thea{}b\theb{}}{a2b3} \OR %
            \equal{a\thea{}b\theb{}}{a3b7} \OR %
            \equal{a\thea{}b\theb{}}{a4b5} \OR %
            \equal{a\thea{}b\theb{}}{a5b1} \OR %
            \equal{a\thea{}b\theb{}}{a6b1} \OR %
            \equal{a\thea{}b\theb{}}{a7b8} \OR %
            \equal{a\thea{}b\theb{}}{a9b9}%
        }{TRUE}{FALSE}\\
    }
\end{document}

I already tried the following measures:

  • to put the a\thea{}b\theb{} parts in an other command;
  • to use the package etex and use the \detokenize{} command as suggested in the answer to this (similar) question.

Non of this changed the result at all.

The previously linked thread also suggests using some TeX's commands but I didn't understand how to use different conditions separed by OR, so I don't know if those work. Anyway, I'd prefer a LaTeX based solution unless the TeX one is really easier.

  • the string a1{}b1{} is visibly different from the string a1b1 so those tests will never be true. drop the {} – David Carlisle Apr 1 '17 at 16:09
  • there's this thing I don't understand: why the output of a\thea{}b\theb{} is a1b1 in the paper, but it's a1{}b1{} if read as a ifthenelse condition? – il mietitore Apr 1 '17 at 16:15
  • \equal is doing an \ifx test on the definition of the internal commands, \def\tempa{a1b1} and \def\tempb{a1{}b1{}} may print the same way if you print them but they have different definitions and for example \typeout{\tempa} would clearly be different to \typeout{\tempb} – David Carlisle Apr 1 '17 at 16:18
1

Drop the {} inside the \equal check -- this is different to what you expect. I also suggest to use a macro that expands to, say, a1b5, in order to get rid off the bunch of a\thea b\theb expressions.

\documentclass{article}

\usepackage{xifthen}
\usepackage{lcg}
\usepackage{pgffor}

\newcounter{a}
\newcounter{b}
\newcounter{SEED}

\newcommand{\Random}[3]{%
    \reinitrand[last=2147483647, seed=\value{SEED}]%
    \rand%
    \setcounter{SEED}{\therand}%
    \reinitrand[first=#1, last=#2, seed=\value{SEED}]%
    \rand%
    \setcounter{#3}{\value{rand}}%
}

\begin{document}
    \ttfamily
    \setcounter{SEED}{10}
    \foreach \num in {1,...,100} {%
        \Random{1}{9}{a}%
        \Random{1}{9}{b}%
        a=\thea\ b=\theb\ a\thea{}b\theb{} %
        \edef\localcheck{a\thea b\theb}
        \ifthenelse{%
            \equal{localcheck}{a2b1} \OR %
            \equal{\localcheck}{a2b3} \OR %
            \equal{\localcheck}{a3b7} \OR %
            \equal{\localcheck}{a4b5} \OR %
            \equal{\localcheck}{a5b1} \OR %
            \equal{\localcheck}{a6b1} \OR %
            \equal{\localcheck}{a7b8} \OR %
            \equal{\localcheck}{a9b9}%
        }{TRUE}{FALSE}\\
    }
\end{document}

enter image description here

Update -- a much shorter version with expl3:

\documentclass{article}

\usepackage{expl3}

\begin{document}
    \pdfsetrandomseed 10 % Set the random seed
    \ttfamily
    \ExplSyntaxOn
    \seq_set_from_clist:Nn \l_compare_patterns_seq {a2b1, a2b3, a3b7, a4b5,a5b1,a6b1,a7b8,a9b9 }% Store the patterns
    \prg_replicate:nn {100} {% Run 100 times
      \tl_set:Nx \l_tmpa_tl {a\fp_eval:n {randint(1,9)}b\fp_eval:n {randint(1,9)}}% Generate the tokenlist
      \tl_use:N \l_tmpa_tl\space
      % Look if the generated tokenlist is contained in the pattern list
      \seq_if_in:NVTF \l_compare_patterns_seq \l_tmpa_tl {TRUE}{FALSE}
      \par% 
    }
    \ExplSyntaxOff
\end{document}
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.