2016年3月16日水曜日

\(\mathrm\TeX\)にも配列

 \(\mathrm\TeX\)には配列が無い。組版処理言語なのだからそんなもの無くて当然である。むしろチューリング完全になってることの方が変態的なのだ。
しかし名前参照=「文字列データを用いて、その文字列と同じ名前をもつ変数を参照する」機能(よくわからん)というモノがあるらしくこれを使って配列を実装してくれていた人が居た。
この人によると「擬似的な」配列らしいがともかく1次元配列として使う分にはそう変わらないらしいので問題ない。ここで\(\mathrm\TeX\)プログラミングにおける著しく面倒くさいポイントがクリア出来る。

 習うより慣れろということで、まずはこのTLarrayパッケージの配列の挙動を掴むために↑のサイトの説明を見ながらスタック処理をやってみる。
スタック処理というのは値を順に格納していき、値を取り出すときは逆に最後に入れた物から順に取り出していく、という操作である。

  1. \makeatletter
  2. \def\countup#1{
  3.         \NewArray{test}
  4.         \@tempcnta=1\relax
  5.         \newcounter{cnt}
  6.         \@whilenum\@tempcnta<#1\relax\do{
  7.                 \@tempcntb=\@tempcnta \multiply\@tempcntb5
  8.                 \PushArray{test}{\the\@tempcntb}
  9.                 \advance\@tempcnta1
  10.         }
  11.         \advance\@tempcnta-1
  12.         \@whilenum\@tempcnta>\m@ne\relax\do{
  13.                 \PopArray{test}\par
  14.                 \advance\@tempcnta-1
  15.         }
  16.         \DestructArray{test}
  17. }
  18. \makeatother

  19. \begin{document}
  20. \countup{6}
  21. \end{document}

 ※サイトでカウンタはなるべく作らないで標準で用意されている\@tempcnta,\@tempcntbを使ったほうが良いとか\loop~\ifnum-\repeatの代わりに\@whilenum-\do{~}が示されていたので、
今回からなるべく従い、@を含む制御綴を使う関係上\makeatletter~\makeatotherを使っている。@のカテゴリコードはその他なので通常は制御綴には使えないが文字に変更することで使えるようになる。\(\mathrm\TeX\)のシステムの大事な所は不用意に書き換えれらないように@を含んだものが多い

 適当にステップ数の5倍を格納して、そのあと逆に取り出していくので出力は
25
20
15
10
5
みたいになるはず。ところが、
????
何故か最後の数字ばっかり出力される。
ありがたいことに配列の中身を列挙する\ShowArray{}コマンドが用意されているので8行目のあとに
 [ \ShowArray{test} ]\par
を追加して実行すると
、とおそらく\@tempcntbが変動するに連れて配列の中身も全部書き換わってしまっている。配列にカウンタそのものが格納されているようだ。
 \theを外すとか\relaxをつけるとか\(\mathrm\LaTeX\)版のカウンタ\newcounter{count}を使ってみるとかいろいろやったがやはりエラーになるかカウンタ自体が格納されてしまう。

 パッケージの中身を直接読める程の技能は私にはないしどうしようかと思い悩んだ末、作者に直接聞いてみようかと思ったら仕様書的なものがパッケージに添付されていることに気がついた。
 いろいろ読んでいくと
ここで \PushArray 命令は⟨値⟩を展開せずに配列に追加するが,後ろに * をつけて \PushArray* とすると ⟨値⟩を完全展開したものを配列に追加することができる.
とあった。これじゃん。3時間も悩んでいた自分がバカみたいだ。

 8行目を \PushArray*{test}{\the\@tempcntb} に書き換えると
期待通りの出力になった。

 これでカウンタと変数が普通のプログラミング言語と同じような計算ができるようになった。

 次は前回やろうとしていた高速で素数を求めるプログラムについて。→次回

-2019-03-12: \(\TeX\)を\(\mathrm\TeX\)に変更

0 件のコメント:

コメントを投稿