(前回の続き)
LISP on TeX (lisp-on-tex パッケージ)
(参照:アレ)
「LISP on TeX」という怖そうな*1パッケージを使うと、LISP 的な言語でプログラミングができる。というわけで早速ナベアツしてみる……。
……と思ったら、自分の思い通りにはいかないことが解った。「3 のつく数」を判定するために、整数値を文字列に変換して文字の検索に持ち込みたいんだが、今のところ、LISP on TeX には文字列を操作する関数が十分に揃っていない。もちろん、自分で十進展開を行えば可能ではあるが、それはやりたくない。*2どうしよう……。
……仕方がないので、作ってみた。
- bxlot-string パッケージ(Gist/zr-tex8r)
これを読み込むと、LISP on TeX の大域環境に次の関数が追加される。
(\explode <文字列s>)
: 文字列 s を文字毎に分解したリストを作る。ただし、グループ({...}
で囲まれた部分)は 1 文字と扱われる。なお、ここで「文字」というのは「文字列(string)」の構成要素のことで「TeX のトークン」に相当する。LISP on TeX に「文字型」はないので、分解後の各要素は 1 文字の文字列となる。「文字」が制御綴である場合でも、「(LISP on TeX の)トークン型」ではなく「文字列型」の値となる。 例:(explode 'a \b {\c d}')
を評価すると値は('a' ' ' '\b' '{\c d}')
となる。
これを利用すると、文字列の操作をリストの操作に帰着させられる。例えば、整数 n が「3 のつく数」かは、(\explode (\intTOstring \n))
の結果のリストに '3'
と一致する要素があるかを調べればよい。
これで、当初の予定通りにナベアツが実装できる。
[nabeazz-lot.tex]
\documentclass{article} \usepackage{lisp-on-tex,bxlot-string} \usepackage{type1cm} \newcommand*\AhoFont[1]{{\usefont{OT1}{cmfr}{m}{it}\LARGE #1}} \newcommand*\NabeAzz[1]{\lispinterp{(\nabeazz :#1)}} \lispinterp{%!!!!!!!!!!!!!!!!!!!!!!!!!!! LISP code (\define \joinstr (\lambda (\sep \lst) (\lispif (\nilQ (\cdr \lst)) (\car \lst) (\concat (\car \lst) \sep (\joinstr \sep (\cdr \lst)))))) (\define \intlist (\lambda (\m \n) (\lispif (\< \n \m) () (\cons \m (\intlist (\+ \m :1) \n))))) (\define \memQ (\lambda (\x \lst) (\lispif (\nilQ \lst) /f (\lispif (\= \x (\car \lst)) /t (\memQ \x (\cdr \lst)))))) (\define \ahoQ (\lambda (\n) (\or (\= (\mod \n :3) :0) (\memQ '3' (\explode (\intTOstring \n)))))) (\define \nazstr (\lambda (\n) (\lispif (\ahoQ \n) (\concat '\AhoFont' (\group (\intTOstring \n))) (\intTOstring \n)))) (\define \nabeazz (\lambda (\n) (\texprint (\joinstr ' ' (\map \nazstr (\intlist :1 \n)))))) }%!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! \begin{document} \NabeAzz{40} \end{document}