ChatGPTのプログラミング能力を素数判定コードを使ってチェックする
ChatGPTに「素数かどうか判定する」コードの生成を依頼し、結果を検証しました。本記事では、AIが生成するコードの実用性と、最適化されたアルゴリズムを生成できるかどうかを考察してみました。
はじめに
ChatGPTで、プログラムを作成させる記事はたくさんあるかと思います。私も、日頃からプログラミングでChatGPTのお世話になっているのですが、演算量やメモリ量を考慮したプログラムを生成するのは少し弱いと感じています。
そこで、どれくらいリソースを考慮したプログラムを作成してくれるか、簡単な問題でチェックしてみました。お題は「Nが素数かどうか判定する関数」です。典型問題でWebにもたくさん情報があり、当然ChatGPTは学習している前提になります。
ということで、できて当然の難易度の低い問題だと思います。
「これくらいは出来てね」という問題になります。
「Nが素数かどうかを判定する関数」を作ってもらう
利用したのは無料で利用できるChatGPT3.5です。とりあえず、最初のプロンプトで計算量を考慮する旨を伝えます。また、言語はpythonとしました。
ある程度指示をしないと、計算量無視のプログラムを作るので最低限は最初から指示しました。
以下、ChatGPTの回答です。エラトステネスの篩を使っている時点で正解ですが、Nが素数かどうか判定したいだけなのに、なぜかリストを作成しています。素数列挙のプログラムのテンプレ実装がこんな感じなので、それを学習しているからでしょうか(コメントまで丁寧なのは感心)。Nの値が$10^13$くらいになると、リストが巨大になってメモリを圧迫するので、このコードイマイチです。
ということで、配列が無駄だと批判してみます。すると以下のコードを出力しました。この時点で、かなり効率化されています。注目するのは、2と3の素数判定を行なって、ループを6刻みにしているところでしょうか。
自分で効率化する場合は、先に2の倍数かチェックしてから2刻みのループを書く程度だと思うので、それより効率化してくれています。ここは、すごいなと感じました。ただ、このせいでループ内の条件判定が増えているので、処理量的には微妙かもですが。
ただ、個人的には、int(math.sqrt(n))
というぶぶんが気に入らないです。ここって、i*i <= N
とすれば整数化できます。
浮動小数点の誤差で苦労した記憶があるので、あまり浮動小数は使いたくないです。
ということで、ここを指示します。すると、while i*i <= n
とちゃんと書き直してくれました。ただ、sqrt_n = int(math.sqrt(n))
といういらない行が残っています(sqrt_n
は参照されていない)。sqrtを消さないのは、ChatGPTが命令に従いたくないという反抗心ですかね・・・
最後は、ちょっと意地悪して、曖昧な指示を出してみました。すると改悪しました(笑)。これ以降、改善→改悪…の無限ループになりました。また、なぜか2の倍数の判定だけ行なってループは2刻みに変更されています。覚えているコードをそのまま出力している感を感じます。
2024年9月追記
1年経ったので上記の問題を改めてやってみました。結果は、最初の質問で2つ目のプログラムを提示してきました。その後は大体同じような感じでした。このレベルの問題については、そこまで進化していない印象です。
なお、AtCoderの問題を解くときなどにたまにChatGPTに投げることがありますが、そのまま使えるコードを出力することは少ない気がします。ただ、問題に対する方向性などに関してはある程度的を得た回答を行うことがあり、解法を思いつかない場合などにアルゴリズムとしてどのような可能性があるかを聞くには良いかと思います。実際、気づきになることが何度かありました。
生成AIは完全に完全な答えを期待するより、「相談相手」として捉えた方がよいかと思います。
Webアプリみたいにテンプレ的な実装は強そうです。実際、その手のプログラムを行うエンジニアは絶賛しています。定型処理は生成AIに奪われるかもですね。
終わりに
プログラミングサポートツールとしてChatGPTは便利ですが、演算量を気にしないコードを吐いてくるので、「計算量を考慮して」という指示は出しておいた方が良いと思います。
単に無駄なだけならいいですが、今回最初に出力してくれたプログラムは、Nが大きくなるとメモリ不足になる可能性もあります。これって、テスト時はOKで実データを入れたら落ちるという原因になりかねないので注意です。
プロンプトに、メモリ量の制約も入れたら考えてくれたのかもと反省
典型アルゴリズムをダイレクトに使う問題は、指示しておけば演算量を考慮してくれるので、ちょっとした関数を作る上では便利に使えるかなと感じています。
おまけ
ただ、実際に使うと、動かないとか、ライブラリの使い方が違うとか結構トラブリます。特に、ライブラリ更新時に仕様変更があったやつは、新旧のライブラリの使用方法が混在したコードを作ってくれて結局、本家のリファレンスを見に行くこともしばしば。
サポートツールとしては優秀ですが、使う方のスキルが求められると感じています。
上のプログラムも、改善してもらうのに、ダメ出しできるスキルは最低限必要