以下の内容はhttps://zrbabbler.hatenablog.com/entry/2025/07/06/024452より取得しました。


イマドキのエ~アイのTeX知識を添削してみた(2)

前回の続き。前回の記事では“純粋な知識問題”を扱いましたが、今回は「実用的なTeX言語プログラミング」を扱います。

例の2022年の記事にある問題でプログラミングを扱っているのは6番目のFizzBuzzですが、FizzBuzzはあまり実用的とはいえないので、ここでは別の問題を扱います。

このシリーズではプログラミングの問題についてはGemini 2.5 Proを使用します。Googleにログインしている状態であれば、GeminiのフツーのWebサイトで無料枠の2.5 Proが使えます。

イマドキのAIのTeXプログラミングを添削する

「“HH:MM”の形式の時刻の文字列」を「0時からの経過分数」に変換する関数を実装します。TeXで“関数”を表現する方法はいくつかありますが、ここでは「値を返す先の変数を引数に渡す」という方式1にします。

「フツーのプログラミング言語から変換させると性能が良くなる2」という話を仕入れたので、ここではRubyの関数から変換させてみました。

RubyのコードではString#splitを使っていますが、TeXsplitを作ろうとすると地獄に陥ります😱 文字列の分割をマクロ引数のパターンマッチに任せるのが“TeX言語らしいやり方”ですね🤯

※この問題ではGemini 2.5 Proを使用しました。

入力したやつ

以下の内容をMarkdown形式で表して入力しました。
def toMinutes(time_str)
time_str.split(':').map{|x| Integer(x)}.then{|(a,b)| a*60+b}
end

このRuby関数と同じことをするTeX言語マクロ\toMinutesを作ってください。インタフェースについては

value = toMinutes("12:30")

の代わりに

\toMinutes\value{12:30}

のようにします。
※パッケージは使わないでください。

出力されたやつ

能書きは一切無視して、最終的なプログラムコードだけを載せます。
% --- マクロ定義ここから ---

% 計算に使用するカウンタ(整数型変数)を宣言
\newcount\hours
\newcount\minutes
\newcount\totalminutes

% \toMinutes の内部で呼び出されるヘルパーマクロ
% #1:#2\relax の形式で引数を取ることで、":"を区切り文字として
% 時間と分を分割します。
% #1: 時間 (HH)
% #2: 分 (MM)
% #3: 結果を格納するマクロ(例: \value)
\def\parseTime#1:#2\relax#3{
    \hours=#1
    \minutes=#2
    \totalminutes=\hours
    \multiply\totalminutes by 60
    \advance\totalminutes by \minutes
    % 計算結果を #3 で指定されたマクロに定義する
    % \edef は右辺を完全に展開してから定義する
    \edef#3{\the\totalminutes}
}

% ユーザーが呼び出すマクロ本体
% #1: 結果を格納するマクロ(例: \value)
% #2: 時刻文字列(例: {12:30})
\def\toMinutes#1#2{
    % \expandafter を用いて、#2の波括弧{}を取り除き、
    % 中身の "HH:MM" を \parseTime マクロに渡します。
    \expandafter\parseTime#2\relax#1
}

% --- マクロ定義ここまで ---

添削してみるやつ

…………ほぼカンペキ(ツマラナイ😐)

インタフェースについて、自分は\valueの部分は整数レジスタを意図していたのですが、AIは“整数値マクロ”と解釈しました。もちろん(明確に指示してないので)それでも正解で、むしろ「LaTeXの命令の実装」としてはその方が適切3かもしれませんね。

マクロの引継の処理
\def\toMinutes#1#2{
    % \expandafter を用いて、#2の波括弧{}を取り除き、
    % 中身の "HH:MM" を \parseTime マクロに渡します。
    \expandafter\parseTime#2\relax#1
}

「ユーザからもらった引数を区切り付き引数のマクロに引き継いで、パターンマッチに持ち込む」という典型的なパターンは卒なくこなせています。ただし\expandafter を用いて、#2の波括弧{}を取り除き、という説明は不適切で、実際にはここでは \expandafter は不要です。なぜなら、マクロの実引数は「マクロ呼出時の波括弧の中身」であり、従って引数#2にはそもそも波括弧は付いていないからです。

\def\toMinutes#1#2{%
    % #2の中身の "HH:MM" を \parseTime マクロに渡します。
    \parseTime#2\relax#1% \expandafter は不要!
}

「引数に含まれるマクロを展開させたい」という意図ならばこの\expandafterも意味をもちますが、時刻文字列の正当な引数は明らかに「単なる文字列」であるため、展開を考えるなら4中途半端な一回展開ではなく完全展開を施すべきです。

\def\toMinutes#1#2{%
    \edef\timestring{#2}% 完全展開する
    \expandafter\parseTime\timestring\relax#1%
}
その他諸々
  • ソースの行末による「余計な空白」が処理できていません。数箇所の行末に%を補う必要がありました。
添削結果

修正後のコード:

実行例
\documentclass{article}
\usepackage{ai-coding-1}
\begin{document}
16:40
\toMinutes\myResult{16:40}
$\to$ {\myResult} minutes
\end{document}

出力結果

カンペキ😍

まとめ

やっぱり、イマドキのエ~アイはマトモなのでツマラナイ😑(ざんねん🙃)

つづく


  1. C言語の関数で「値を返す先の変数のポインタを引数に渡す」のと同じ発想です。
  2. 性能云々以外に「所望のプログラムの仕様を自然言語で正確に記述する手間を省ける」という点も大きいかもしれません。
  3. LaTeXでは「TeXの整数型のレジスタ・パラメタ」を直接には扱わないため。
  4. もちろん、今回の仕様では完全展開を明示的に要求していないので、そうする必要はありません。



以上の内容はhttps://zrbabbler.hatenablog.com/entry/2025/07/06/024452より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14