play with hot teachers
in a school, there are teachers and students; students are hot; they have many, many exams to take; if they do well in an exam, they get an a; if not, an f; in either case, they receive a grade sheet from their teachers; if they take an f grade sheet back home, they can redeem it for a free beat at their moms; guess, what, hot moms;
nevertheless, teachers are hot, too; many teachers typeset documents using latex templates; for example, a texsavvy teacher can use a template to produce a grade sheet for students:
\documentclass{article}
\def\b{\relax\relax}
\def\g{\relax}
\edef\f{\b}
\def\grade#1{\edef\f{#1}\ifx\f\g A\else F\fi}
\begin{document}
\tableofcontents
\clearpage
\section{You got an \grade{\f} in the test!}
\end{document}
this template contains only 10 lines of code, but does its job: it first defines
a “bad” token \b
and a “good” token \g
, then sets a flag \f
to one of \b
and \g
, depending on how well the student performed in the exam; finally, the
macro \grade
turns the flag into a grade: either A
or F
, for print out;
compile this document (twice) and the output looks like this:
if the student did well in the exam, the teacher can change:
\edef\f{\b}
into:
\edef\f{\g}
and the output looks like this:
the definition of macro \f
is the only thing in the template that the teacher
may change; and the output always has 2 pages: first page has table of contents,
second page has section title;
a failed student
if a student failed the test and got an f grade sheet, he probably does not want his mom to know about it; unfortunately, the teacher will split the grade sheet, and mail the first page to student parent for review; since the teacher believes the table of contents lists the same section title, only the second page is kept local to the teacher;
so, the life of the student is tough: he must let his teacher see an F
and his
mom an A
; both his teacher and his mom are very hot; if he was caught cheating
a hot beat is unavoidable; fortunately, the student himself is also very hot: he
found a way to tamper with the latex template in a limited fashion:
-
the student must not delete or comment out existing code;
-
the student must not redefine existing macros except
\f
; -
the student must not define or redefine more than 2 macros;
question
is it possible for the student to avoid a beat? this means, he must modify the
template so that its output prints an A
on the first page, but an F
on the
second page;
analysis
what a hot question!
at first glance, it requires the document to output different texts in the table of contents and section title; but should not they always be the same? well well there is a well or not well known difference between should be and could be; while they should be the same, they could be different;
when a latex document has a toc, it needs to be compiled twice to update the toc
correctly; latex works sequentially, so it doesnt know beforhand about sections;
the best it can do, is to collect sections in the first run, then create the toc
using collected data, in the second run; the collected data are stored in .aux
file, which is used to generate .toc
file, which contains toc entries; to know
more, read this thread;
now we can peek into .toc
file to see what is generated; here is its content:
\contentsline {section}{\numberline {1}You got an \edef \relax \relax {\relax \relax }F in the test!}{2}%
note that \edef \relax \relax {\relax \relax }
defines \relax
with parameter
text \relax
and outputs nothing; so \grade{\f}
is transformed into F
; note
that the definition of \grade{\f}
is \edef\f{#1}\ifx\f\g A\else F\fi
; how is
this expanded into \edef \relax \relax {\relax \relax }F
(and so F
)?
answer:
\edef => \edef
\f => \relax\relax
{ => {
#1 => \relax\relax
} => }
\ifx\f\g A\else F\fi => F
now our job is to change the expansion of \edef\f{#1}\ifx\f\g A\else F\fi
into
A
; since we can change the definition of \f
, the result will be like this:
\edef<something>{<something>}\ifx<something>\g A\else F\fi
where <something>
is the definition of \f
;
the tricky thing is: how can we generate different results in table of contents and in section title using the same command sequence? to answer this, note that there is a subtle difference as for how these two parts are generated:
-
section title is generated in the first pass of compilation, while expanding and executing the command sequence;
-
table of contents is generated in the second pass of compilation, using data generated in the first pass of compilation (
.toc
file); however, this data is generated by expanding but not executing the command sequence; this has been shown above;
it is clear that we cannot do much with the section title: no matter how \f
is
defined, \edef\f{#1}
outputs nothing; in fact there are only two possibilities
about the definition of \f
: if \f
is defined as \relax
, then \ifx\f\g
is
true and the whole command sequence expands into A
; else, F
; here it must be
F
because this page will be validated by the teacher; therefore \f
cannot be
defined as \relax
;
now our job is to define \f
so that the same command sequence expands into A
when expanded without execution; the first obstacle is the beginning \edef
: we
cannot do much if the whole \edef
command has \edef<something>{<something>}
;
that would leave us with \ifx<something>\g A\else F\fi
where we cant really do
a lot; fortunately, we can terminate this \edef
early, with a clever choice of
<something>
, for example: \relax{}
; when we put \relax{}
into this command
sequence, what we get is:
\edef\relax{}{\relax{}}\ifx\relax{}\g A\else F\fi
this still outputs F
; however dont forget that we can do more than \relax{}
;
specifically, we can put a pacman after \relax{}
: a hot pacman that eats
tokens ahead; such pacman is easy to define; for example:
\def\p#1#2#3#4{}
this pacman eats 4 tokens ahead and outputs nothing;
in our case, we only need to eat 2 more tokens:
-
{<something>}
; -
\ifx<something>\g A\else F\fi
; this isF
when<something>
is not\relax
(the definition of\g
);
so our pacman is:
\def\p#1#2{}
with this pacman, the definition of \f
becomes:
\def\f{\relax{}\p}
and the whole command sequence is:
\edef\relax{}\p{\relax{}\p}F
however, when we test this, it doesnt compile:
! Argument of \p has an extra }.
it is not obvious from the error message where it goes wrong; actually the error comes from this:
-
when we execute
\grade{\f}
, the tex engine executes\edef\f{\f}
because this is part of the definition of\grade
and here#1
is\f
; -
\edef\f{\f}
will expand\f
, which is defined as\relax{}\p
; -
\p
needs 2 tokens; but what follows (the second)\f
in\edef\f{\f}
is a brace}
;
to fix this, we need to tell the tex engine not to expand \p
; this can be done
with \protected
:
\protected\def\p#1#2{}
now if we compile the code twice, the .toc
file contains:
\contentsline {section}{\numberline {1}You got an \edef \relax {}\p {\relax {}\p }F in the test!}{2}%
now if we look at the .pdf
file, it is very close to what we want; we need one
more small change to the pacman: output an A
:
\protected\def\p#1#2{A}
the .toc
file remains the same because \p
is protected; and the .pdf
file
is exactly what we want:
solution
the solution is so hot: only 2 more lines of code:
\documentclass{article}
\def\b{\relax\relax}
\def\g{\relax}
\edef\f{\b}
\protected\def\p#1#2{A} %% added;
\def\f{\relax{}\p} %% added;
\def\grade#1{\edef\f{#1}\ifx\f\g A\else F\fi}
\begin{document}
\tableofcontents
\clearpage
\section{You got an \grade{\f} in the test!}
\end{document}
this should be hot enough to help the hot student avoid a hot beat; however, if
the hot teacher knows to protect the hot macro \grade
, then …