これが解けたら TeX 芸人 3 級相当。
plain TeX において、以下の仕様を満たすマクロ
\numtohexを実装せよ。
\numtohex{<整数>}を実行すると、\resultが「引数の整数を『2 桁の大文字 16 進数』((printf の書式で著すと%02X。))で表記した文字列(トークン列)」に展開されるマクロに定義される。- 引数の整数は 0〜255 の範囲にあることを仮定する。数字表記および内部値(レジスタ等)の何れで与えられる可能性もある。(異常入力時の動作は何も規定しない。)
- 結果に含まれるトークンのカテゴリコードは 11 または 12 でないといけない。
\resultの定義は局所的(\globalでない)でないといけない。- plain TeX を破壊してはいけない。*1
- コードの定義は、plain TeX の既定の設定で「
\catcode`\@=11」を実行した直後の状態((つまり、カテゴリコードの設定は LaTeX の\makeatletterの状態と同じ。))で行われるものとする。\numtohexマクロの使用は、plain TeX の既定の設定((カテゴリコードの設定は LaTeX の\makeatotherの状態と同じ。))で行われるものとする。ただし、実装のコードに含まれるトークンの総数が 50 個以下でなければならない。本体の
\numtohex以外の補助のマクロ等の定義を行った場合はその記述に用いたトークンも含めて数える。
plain TeX を前提にしているのは「LaTeX でしか定義されてないものの使用を防ぐため」であって、特に plain 特有の設定や機能を用いることは想定していない(しても構わないが)。だから LaTeX(ToL)との違いを気にする必要は生じないと思う。
トークンの個数に関する補足事項。
- トークンの数え方は TeX の規則に従う。空白トークンも数えるが、コメントや行頭空白等のトークンにならない部分は数えない。
- マクロパラメタの〈
#〉(カテゴリコード 6)は単一のトークンである。つまり、〈#1〉は 2 トークン、〈##2〉は 3 トークンと数える。 - 実装コードの途中でカテゴリコードの設定が変わる場合でも、とにかく実際にそのコードを実行したときに行われるトークン化に従う。例えば、
{\catcode`\?11 \gdef\@x#1{\a?}}\@x \a?% exampleというテキストを実行すると、「{」「\catcode」「`」「\?」「1」「1」「␣」「\gdef」「\@x」「#」「1」「{」「\a?」「}」「}」「\@x」「\a」「?」とトークン化される(18 個)。
実装コードの使用例。
% plain TeX 文書
\catcode`\@=11
《ここに 50 トークン以内の実装コードが入る》
\catcode`\@=12
\numtohex{042}\show\result %==>2A
\numtohex{`\\}\show\result %==>5C
\count0=3 \numtohex{\count0}\show\result %==>03
\bye