AIが書いたコードを自分の言葉にする

· Updated:

前回、O’Reillyのサブスクに登録して「作る → AIに聞く → 気になったら本を読む」でやってみる、と書いた。

最近、Rustの勉強を兼ねて、業務でも使えそうな小さなCLIツールを作っている。基本的には自分で考えつつ、わからないところはAIに聞きながら進めている。 今回は、AIと一緒に書いたコードをあとから読み直してみた。

題材にしたのは、2つのイベントが近い時間に起きているかを調べる処理。自分だったらどう書くだろう、と考えてみると、最初に浮かんだのは二分探索だった。片方のイベントをソートしておいて、もう片方の各イベントについて、近くにあるものを探す。たぶんそれでも書ける。 でも、実際のコードはそうなっていなかった。

両方のイベントをあらかじめソートして、2つの列を前から順番に見ていく。片方の位置を示すポインタは前に進むだけで、一度通り過ぎたところには戻らない。いわゆるTwo Pointers(2ポインタ)のやり方だった。 最初は「なるほど、こっちのほうが速いのか」くらいに思った。でも、もう少しコードを追ってみると、面白かったのはアルゴリズムそのものではなかった。 なぜ「戻らなくていい」のか。 調べる側のイベントがソートされていて、時刻が順番に大きくなっていくから、一度通り過ぎたところには戻らなくていい。もう片方もソートされているから、前から順番に見ていけば判定できる。 当たり前といえば当たり前なんだけど、この「ソートされている」という前提が、コードの別の場所にあった。

nanos.sort_unstable();

最初に読んだとき、この一行は単に入力を整えているだけだと思っていた。でも、ここでソートしているから、その後の処理では「もう見たところには戻らない」と決められる。 別々の場所にあるコードが、実はひとつの設計になっていた。

AIとコードを書いていると、こういうことが結構ある気がする。コードは動く。テストも通る。実装としても悪くない。だから、そのまま次に進めてしまう。 でも、自分がそのコードを理解しているかというと、また別の話なんだと思う。今回も、Two Pointersという名前を覚えたことより、「なぜこの実装が成立するのか」を追いかけたことのほうが収穫だった。 コードを読んでいると、一見すると独立して見える処理が、別の場所の実装を成立させていることがある。さっきのソートが、まさにそれだった。設計を理解するというのは、コードを一行ずつ説明できることより、こういう処理同士のつながりを見つけることなのかもしれない。

AIはかなりいいコードを書いてくれる。だから最近は、「自分で全部書けたか」だけを気にしても、あまり意味がない気がしている。それより、「自分だったらどう書くか」を一度考えて、AIが書いたものと比べる。違っていたら「なんでこっちなんだろう」と調べる。そこで本を読む。 今回も、二分探索だと思っていたものがTwo Pointersだった、という小さな違いから、ソートと計算量の話を調べて、最終的には「この処理とこの処理は、どうつながっているんだろう」というところまで戻ってきた。

こういう寄り道なら、悪くない。 「動いた。よし次」で進めるのも速いけど、たまには立ち止まって、AIが書いたコードの「なぜ」を自分なりに追いかけてみる。しばらくは、そんな感じでやってみようと思う。 O’Reillyのサブスクも、たぶんこういう使い方なら元が取れる。

たぶん。

← Back to posts