0番染色体

科学は全世界を照らす光である

TeX de Quine!!

最近『あなたの知らない超絶技巧プログラミングの世界』なる本が発売され,好評なようです.

あなたの知らない超絶技巧プログラミングの世界

あなたの知らない超絶技巧プログラミングの世界

その影響を受け,私の周辺ではちょっとしたQuine *1 ブームが到来しています.ということで,今回はTeX/LaTeXで「なるべく短いQuine」を作成することに挑戦してみました.

TeX

TeX言語を用いたQuineについてはウィスコンシン大学のミラー教授によって先行研究が行われていました.下記のコードをTeXで処理するとdviファイルにまったく同じコードがタイプライタ体で出力されます.

\obeylines\nopagenumbers\tt\def\[#1]#2[#3[#4
#5{#1obeylines#1nopagenumbers#1tt#1def#1[#21]#22[#23[#24
#25#3#5#4#1[#1char92]#1#2[#1char123[#1char125
#3#1[#1#21]#1#22[#1#23[#1#24
#3#1#25#4#4#1bye}\[\char92]\#[\char123[\char125
{\[\#1]\#2[\#3[\#4
{\#5}}\bye

出典:https://www.math.wisc.edu/~jmiller/Quines/tex.html

私はあまりTeX言語に詳しくないので,これよりも短いQuineを書く方法は思いつけませんでした.

LaTeX

次にLaTeXでQuineを書くことを考えます.これについても,先行研究が存在していました.

TeX Quine - 鵺帝国領ブログ

こちらはもう少し短いコードでもQuineを作ることができそうです.ということで作ってみました.

\documentclass{article}
\thispagestyle{empty}
\usepackage{geometry}
\usepackage{alltt}
\let\l\let\l\d\def
\d\t{}\d\k{}\d\){\}\\\+}\d\+{\char"5C}
\l\[\{\l\]\}\l\-\+\l\?\#\l\!\\
\d\q#1{\+documentclass\{article\)thispagestyle\{empty\)usepackage\{geometry\k
\)usepackage\{alltt\)let\+l\+let\+l\+d\+def\\\+d\+t\{\}\+d\+k\{\}\+d\+)\{\+\k
\}\+\+\++\}\+d\++\{\+char"5C\)l\+[\+\{\+l\+]\+\}\+l\+-\++\+l\+?\+\#\+l\+!\+\k
\+\\\+d\+q\#1\{\t#1\)begin\{document\)begin\{alltt\)q\{\{\+d\+t\{\+-t\+?1\}\k
\+d\+k\{\+-k\+!\}\+d\++\{\+-+\}\+d\+\+\{\+-\+-\}\+d\+\{\{\+-\+[\}\+d\+)\{\+\k
-)\}\+d\+\}\{\+-\+]\}\+d\+\#\{\+-\+?\}\+q\{\}\}\)end\{alltt\)end\{document\}}
\begin{document}
\begin{alltt}
\q{{\d\t{\-t\?1}\d\k{\-k\!}\d\+{\-+}\d\\{\-\-}\d\{{\-\[}\d\){\-)}\d\}{\-\]}\d\#{\-\?}\q{}}}
\end{alltt}
\end{document}

出力結果はこんな感じです.

LaTeX Quine

初めてのQuine製作ということで,あまり画期的なアイデアも浮かばず,なるべく短くなるように小手先の工夫をしながら,単純な発想を愚直に実装してみたという感じです.

  • 標準のverbatim環境だけだと辛いので,allttパッケージを利用している
  • 少しでも短くするために変なマクロを組んだので可読性が犠牲になっている
  • コントロール・シンボルを活用することで半角スペースを使用せずに済ませている

発想の単純さとは裏腹に,コードの見た目が少々エグいのはこのような理由によるのだろうと思われます.

LuaLaTeX

LuaLaTeXではLua言語が使えるので簡単にQuineを実現することが可能……かと思いきや,2言語 *2 を同時に扱わなければいけないため,むしろ難易度が上がったように感じました.

LuaLaTeXは基本的にLaTeXに対して上位互換のはずなので,当然さきほどのLaTeXによるQuineコードがそのまま使えるわけですが,それでは面白くないのでLuaの機能は必ず使うことを前提としています.その結果,LaTeX-Quineよりも邪悪なコードが完成しました.

\documentclass[landscape]{article}\usepackage[a0paper]{geometry}\parindent=0pt\begin{document}\ttfamily\tiny\catcode`\|0 |catcode`|<1 |catcode`|>2 <|catcode`|\11 |directlua<a=string.char(124)b=string.char(60)c=string.char(62)s=[[tex.write("\\documentclass[landscape]{article}\\usepackage[a0paper]{geometry}\\parindent=0pt\\begin{document}\\ttfamily\\tiny\\catcode`\\"..a.."0 "..a.."catcode`"..a..b.."1 "..a.."catcode`"..a..c.."2 "..b..a.."catcode`"..a.."\\11 "..a.."directlua"..b.."a=string.char(124)b=string.char(60)c=string.char(62)s=[".."["..s.."]".."];"..s..c..c..a.."\\end{document}")]];tex.write("\\documentclass[landscape]{article}\\usepackage[a0paper]{geometry}\\parindent=0pt\\begin{document}\\ttfamily\\tiny\\catcode`\\"..a.."0 "..a.."catcode`"..a..b.."1 "..a.."catcode`"..a..c.."2 "..b..a.."catcode`"..a.."\\11 "..a.."directlua"..b.."a=string.char(124)b=string.char(60)c=string.char(62)s=[".."["..s.."]".."];"..s..c..c..a.."end{document}")>>|end{document}

LaTeXで出力するのにうまい具合に改行を入れる方法を思いつかなかったので966文字ありますが一切改行のない1行コードです.これをLuaTeXで処理すると,A0用紙に\tinyサイズで同じコードが出力されます.

LuaLaTeX Quine

全然読めませんね.仕方がないのでここに拡大可能なPDFを置いておくことにします.

当初は「なるべく短く書く」ことを目標にしていたわけですが,LuaとTeXのコンビネーションが辛かったことにより途中から「Quineの定義を満たせば何でもいい」という気になったため,このようなものが出来てしまいました.

  • TeX on LaTeXな上にLua言語が混在している
  • 技術的な理由により改行がまったくない
  • 通常は変更することのない文字種のカテゴリーコードを複数変更している

ため可読性は非常に残念な感じになっています.

おわりに

結局,私の作成したQuineは「Quineである」ということだけが取り柄で,特に「短く」も「美しく」もないものとなってしまいました.私を含め「もっと質の良いQuineを見てみたい!」という人は,今後このQuineブームがTeX界にも広がり,たくさんの洗練されたQuineを鑑賞する機会に恵まれることを期待することにしましょう.

*1:Quineとは,実行すると自らのソースコードを出力するプログラムのことです.

*2:TeXとLaTeXを分けて数えるのであれば3言語.