これでいいのかなぁ?
TeX芸人検定への解答.
\catcode`@=11 \def\xx@q@end{\xx@q@@end} \def\xx@q@head{\afterassignment\xx@q@calc\let\xx@q@temp= } \def\length#1{\xx@q@head#1\xx@q@end} \def\xx@q@calc{% \show\xx@q@temp \ifx\xx@q@temp\xx@q@end \let\xx@q@next\relax \else *\let\xx@q@next\xx@q@head \fi\xx@q@next} \tracingmacros=1 \length{hoge \fuga {group\piyo}} %************** \bye
こーゆー事なのだろうか?
修正その一
そっこーで違うと把握(\edefでこれを使えない.).まじか……
これから卒業論文などでLaTeXを使う人へ向けて
余り書くことがないので,LaTeXの初心者への注意点を書いてみる.
所属研究室での使用状況がわりとひどかったから……
その情報は古くなってないですか?
{\it ...}とかで書体変更はしない方がいい
この書体変更法は昔(LaTeX 2.09)時代のものです.現在では,\textitなどの命令を使うのが一般的です.古い方法では,例えば「イタリックかつボールド」なんて指定をやろうとすると苦労するはずです.もちろん,イタリック体を表示するために$で囲むのは論外です.
EPSに変換しなければいけないという時代は終わった気がする
卒業論文を書く環境では,DVIPDFMxを使ってPDFに変換することが一般的になってきました.LaTeX用のエディタもそのような設定になっているはずです.その環境でわざわざEPSに変換することはほぼ無意味です.PNGやJPEGが使えます.PDFそのものが埋め込めたりもします.DVIOUTやxdviなどがその表示に対応していないだけです.Adobe Readerあたりで見ればちゃんと画像は入っています.
どこから情報を得ればいいのさ?
美文書だったり独習だったりが初心者向けのベストチョイスだと信じています.
版面変更はgeometry.styがいいと思うんだ
我が大学の出身学科では,レポート用のテンプレートが公開されていて,卒業論文でもそれをコピーして使う人が多いようです.更にそれをよくわからないまま改変する奴がいます.特に多いのが,余白などのレイアウト指定を変更する人です.あのテンプレートを含め,よくある方法では版面の変更を\setlengthなどを利用して行います.それはLaTeXの範囲で正しいコードです.しかし,よくわからないまま使うのはおすすめできません.よくわからないエラーが出て,よくわからなものが出来上がります.
それならば,geometry.styを使うのがいいと思うのです.使い方は調べればすぐに出てくるので割愛.
EeePC 901 に Arch いれてみたったー
ちょっとしたお遊びでやったもの.EeePC 901*1に現行のisoを使って Arch Linux を入れるお話.方針は
基本的には ココを見ればいいのだけれど,怠けようとしたりすると詰まるので私が詰まった点をメモ.
UNetBootin が腐っている
UNetBootin に Arch あるじゃんとかいってこれ使うと泣きます.ブートでエラーになりましたとさ.ちなみに iso 落としてきてもダメだった.
/etc/mkinitcpio.conf は書き換えないとダメ
SD に入れる場合のみかもしれない.デフォルトでは usb が入っていないので入れておく.こうしないと SD が見つからないという悲惨な目に遭う.
あとは問題なくいけた.USB からインストールしてデバイスノード名周りで苦労するのはよくあることなので割愛.X はまだ入れてない.
*1:めっさ古い
TeXで競技プログラミングは可能か?
ジャッジシステムないので無理ですが.
というのも残念なので,まずはそもそも解くことができるかについて.問題はAtCoder Regular Contest #005のA,B,C*1.
A
コード
% const data \def\tki{TAKAHASHIKUN} \def\tkii{Takahashikun} \def\tkiii{takahashikun} \def\solve#1.{\ssolve#1 \relax.} \def\rrelax{\relax} \newcount\lovetk \def\ssolve#1 #2.{% \def\cmp{#1}% \def\chkend{#2}% % Is \cmp 'takahashikun' word? \ifx\cmp\tki\advance\lovetk1\fi \ifx\cmp\tkii\advance\lovetk1\fi \ifx\cmp\tkiii\advance\lovetk1\fi \ifx\rrelax\chkend\else % data owari? \ssolve#2.\fi} \read-1to\stdin % read #words \read-1to\stdin % read sentence \expandafter\solve\stdin \immediate\write16{\the\lovetk}% \bye
B
- テーブル作って実装するだけ
コード
% move direction \newcount\dx\dx0 \newcount\dy\dy0 \newcount\x \newcount\y \read-1to\tmp % readline % function set x,y,W \def\setfirstline#1 #2 #3.{% \x#1\relax \y#2\relax \def\W{#3}} \expandafter\setfirstline\tmp. \def\calcW#1#2{\ccalc#1\ccalc#2} \def\ccalc#1{% \if#1R\dx1\fi \if#1L\dx-1\fi \if#1U\dy-1\fi \if#1D\dy1\fi} % function : W -> dx,dy \expandafter\calcW\W\relax \newcount\readline\readline1 % set map data \def\setline#1#2#3#4#5#6#7#8#9{% \expandafter\def\csname data\the\readline1\endcsname{#1}% \expandafter\def\csname data\the\readline2\endcsname{#2}% \expandafter\def\csname data\the\readline3\endcsname{#3}% \expandafter\def\csname data\the\readline4\endcsname{#4}% \expandafter\def\csname data\the\readline5\endcsname{#5}% \expandafter\def\csname data\the\readline6\endcsname{#6}% \expandafter\def\csname data\the\readline7\endcsname{#7}% \expandafter\def\csname data\the\readline8\endcsname{#8}% \expandafter\def\csname data\the\readline9\endcsname{#9}} % read map from stdin \loop\ifnum\readline<10 \read-1to\tmp \expandafter\setline\tmp \advance\readline1 \repeat \newcount\chk \def\buffer{} \readline1 % output \loop\ifnum\readline<5 \edef\buffer{\buffer\csname data\the\y\the\x\endcsname}% \advance\readline1 \chk\x\relax \advance\chk\dx\relax \ifnum\chk<1\multiply\dx-1\relax\fi \ifnum\chk>9\multiply\dx-1\relax\fi \advance\x\dx\relax \chk\y\relax \advance\chk\dy\relax \ifnum\chk<1\multiply\dy-1\relax\fi \ifnum\chk>9\multiply\dy-1\relax\fi \advance\y\dy\relax \repeat \immediate\write16{\buffer} \bye
C
- 幅優先探索で解いた.
コード
\read-1to\stdin % read one line from stdin to \stdin % read H and W \newcount\h \newcount\w \def\readHW#1 #2\relax{% \h=#1\relax \w=#2\relax} \expandafter\readHW\stdin\relax % read map \newcount\loopcnt \newcount\tmpw \newcount\sh \newcount\sw \def\setmap{% \tmpw=0\relax\expandafter\setmapp\stdin\relax} \def\setmapp#1#2{% \expandafter\def\csname map\the\loopcnt:\the\tmpw\endcsname{#1}% \if#1s \sh=\loopcnt \sw=\tmpw \else\fi \ifx#2\relax\def\next{}\else\def\next{\setmapp#2}\fi \advance\tmpw1\relax \next} \catcode`\#=12\relax \loop\ifnum\loopcnt<\h \read-1to\stdin \setmap \advance\loopcnt1\relax \repeat \catcode`\#=6\relax % init deque data \let\Data\relax \edef\deque{\Data{\the\sh:\the\sw,0}} \def\empty{} % function : get topdata to \pos and \brcnt \def\getdata#1{\expandafter\ggetdata\expandafter#1\deque\relax} \def\ggetdata#1\Data#2#3\relax{% \def#1{#2}\def\deque{#3}\parsePosBreak#2\relax} \def\parsePosBreak#1,#2\relax{% \brcnt=#2\relax \def\pos{#1}} % Breadth first search \catcode`\#=12\relax \def\start{s} \def\goal{g} \def\kabe{#} \def\michi{.} \catcode`\#=6\relax %search main \newcount\brcnt \newcount\tw \newcount\th \def\search#1:#2(#3,#4){% \th=#1\relax\advance\th#3\relax \tw=#2\relax\advance\tw#4\relax \expandafter\ifx\csname map\the\th:\the\tw\endcsname\kabe % KABE NO NAKA NI IRU \ifnum\brcnt<2 \advance\brcnt1 % add to tail \edef\deque{\deque\Data{\the\th:\the\tw,\the\brcnt}} \advance\brcnt-1 \fi \else % add to top \edef\deque{\Data{\the\th:\the\tw,\the\brcnt}\deque}% \fi} \def\pos{} \def\checked{true} \def\solve{\let\next\relax% \ifx\deque\empty\immediate\write16{NO} % empty! \else \getdata\data % get top data \expandafter\ifx\csname flag\data\endcsname\checked % checked before -> continue \let\next\solve \else\expandafter\ifx\csname map\pos\endcsname\relax % out of map \let\next\solve \else % check \expandafter\let\csname flag\data\endcsname\checked \expandafter\ifx\csname map\pos\endcsname\goal % GOAL now \immediate\write16{YES}\let\next\relax \else \expandafter\search\pos(0,1)% \expandafter\search\pos(0,-1)% \expandafter\search\pos(1,0)% \expandafter\search\pos(-1,0)% \let\next\solve \fi \fi\fi \fi\next} \solve \bye
現在の LISP on TeX における環境の実装と問題点
今日は LISP on TeX (https://bitbucket.org/hak7a3/lisp-on-tex) の環境の実装および問題点について.
現状,LISP on TeX *1 の環境は次のようなトークン列になっています.
\keyi{valuei}\keyii{valueii}……\keyn{valuen}
対応を追加する際には,トークン列の先頭にペアを書き込む形になっています.\keyhogeに対応する値を引き出す際は,マクロの書式指定文字列を使ってとリ出すようにするといけます.実際,LoT の初期の(裏)目的のひとつは,「TeX でまともなプログラミングをするためのライブラリが作成できたら嬉しいな」*2だったりしました.その影響で,環境周りの制御綴りには@が入っていなかったりします.
さて,これを使って LoT の環境を構築した時の問題点です.それは
- set! の実現が困難
- letrec の実現も困難
の二点です.これは,環境が「ポインタ」的に扱われていないことが要因です.set! では環境を共有しているすべてのものに変更が波及しないといけませんが,クロージャが環境をトークン列として持っているため,どの部分で他と共有しているかを判断できません.また,letrec の場合はクロージャが自身への参照を持つこととなり,環境が無限列となり崩壊します.
例外的に,大域環境は \@globalenv というマクロで定義され「ポインタ」的に扱える関係上,これらの制限がありません*3.
解決方法的な何か
値を一段「ポインタ」的な何かに変更
コード例
\keyi{indexi}\keyii{indexii}……
制御綴り [env@indexi]*4が valuei に展開されるように定義します.index は一意になるようなものを振ります.現状の LoT の cons セルがこれに近い実装になっています*5.今の実装をほとんど変えずにいけるけど,いい手だと思えない.
思い切って,リスト構造にする
こんな感じ
\envi -> \envii\keyi{valuei} % next, key, value
このように定義した \envi を持ち歩く.環境への追加に関して少し考慮すべきな点が*6.
さーて,どうしようかな……
おまけと言う名の私信 Twitter の反応
*1:以下,長いのでLoT
*2:そもそも近代的な言語には程遠いんだから無理という観点は除く
*3:だから,bitbucketのサンプルでは再帰関数が動いている
*4:伝統に則り,制御綴りは四角で囲んで表記してみました.わからない人は \csname env@indexi\endcsname と思っていただけると?
*5:set-car!とかが簡単
*6:実力の無さとも言う
始めてみた & LISP on TeX でナベアツ
主にプログラム,特にTeX関連で書かれるであろう日記を始めてみた.
最初の記事がTeXの濃い話,ナベアツする件について.問題の初出はココ.
これを拙作 LISP on TeX (https://bitbucket.org/hak7a3/lisp-on-tex)でやってみた.
ソースコードはこんな感じ
\documentclass{jarticle} \usepackage{lisp} \begin{document} \font\hoge=cmfi10 \def\NabeAzz#1{\lispinterpl{ (\define \nabe (\lambda \i (\lispif (\= (\- \i :1) :#1) '' (\concat (\internabe \i) ' ' (\nabe (\+ \i :1)))))) (\define \internabe (\lambda \m (\lispif (\= (\* (\/ \m :3) :3) \m) (\group (\concat '\hoge' (\strOfInt \m))) ((\internabei \m) :1)))) (\define \internabei (\lambda \i (\lambda \base (\lispif (\< \i \base) (\strOfInt \i) (\lispif (\= :3 (\/ (\- \i (\*(\/ \i (\* \base :10)) (\* \base :10))) \base)) (\group (\concat '\hoge' (\strOfInt \i))) ((\internabei \i) (\* \base :10))))))) (\print (\nabe :1))}} \tracingmacros=1 \NabeAzz{40} \end{document}
なんかLISPっぽいコードが書けるのが特徴.シンボルはTeXの制御綴り,:num で整数,'string'で文字列(正確にはTeXのトークン列).剰余がないので*1,除算と乗算と減算の組み合わせで実現している.\lispif はif文.\lambdaは一引数関数のみを定義できる.適当にカリー化する必要あり.
出力はこんなのが得られる.
ちなみに,\NabeAzz{1000}とやるとLaTeXが落ちた……
*1:さっさと実装すべき