はじめに
先日Gemini CLIが発表され、話題になっていたので試してみました。
通常のGeminiとは異なり、ファイルを指定して依頼できるとのことだったので、早速試してみました。
環境
node -v
v22.16.0
詳しい使い方やインストール方法は、こちらをご確認ください。
https://github.com/google-gemini/gemini-cli
試してみる
今回コードレビューを依頼するコードです。
コメントに記載の通り、数値の配列から欠落している1つの数値を返す関数です。
/**
* 1からNまでの数値が格納された配列から、欠落している1つの数値を検索します。
* 配列はユニークな数値を含み、1つの数値のみが欠落していると仮定します。
*/
export const findMissingNumberSum = (arr: number[]): number => {
const n = arr.length + 1;
const expectedSum = (n * (n + 1)) / 2;
let actualSum = 0;
for (let i = 0; i < arr.length; i++) {
actualSum += arr[i];
}
return expectedSum - actualSum;
};
findMissingNumberSum([1, 2, 3, 5]);
// 4
findMissingNumberSum([2, 3, 4, 5, 6, 7, 8, 9, 10]);
// 1
Gemini CLIを起動して、コードレビューをお願いしてみます。
@findMissingNumberSum.ts コードレビューして
すると、以下のような返答がありました。
✦ findMissingNumberSum.ts のコードレビューを行います。
この関数は、1からNまでの数値が格納された配列から欠落している1つの数値を効率的に見つけるための、数学的に正しいアプローチ
を採用しています。
良い点:
* 正確性: 算術級数の和の公式 n * (n + 1) / 2
を利用して期待される合計値を計算し、実際の合計値との差から欠落している数値を導き出すロジックは正確です。
* 効率性:
* 時間計算量: 配列の要素を一度だけループするため、O(n)
の時間計算量です。これは、すべての要素を一度は確認する必要があるため、最適なパフォーマンスと言えます。
* 空間計算量: いくつかの変数を保持するだけで、O(1) の空間計算量です。
* 可読性: 変数名 (n, expectedSum, actualSum)
は明確で、関数の目的を正確に表しています。JSDocコメントも関数の役割と前提条件をよく説明しています。
改善点(軽微な提案):
* ループの書き方: 現在の for ループは問題ありませんが、現代のJavaScript/TypeScriptでは for...of ループや reduce
メソッドを使用することで、より簡潔に記述できます。
* for...of を使用する場合:
1 let actualSum = 0;
2 for (const num of arr) {
3 actualSum += num;
4 }
* reduce を使用する場合:
1 const actualSum = arr.reduce((sum, num) => sum + num, 0);
どちらも機能的には同等ですが、for...of はシンプルで読みやすく、reduce
は関数型プログラミングのスタイルを好む場合に適しています。
考慮事項:
* 前提条件: JSDocに記載されている「配列はユニークな数値を含み、1つの数値のみが欠落していると仮定します」という前提は非
常に重要です。もしこれらの前提が満たされない場合(例: 重複する数値、複数の欠落、1からNの範囲外の数値)、関数は期待通
りに動作しません。この前提がコードのコメントとして明確にされているのは素晴らしいです。
* 数値の範囲: n が非常に大きい場合、expectedSum の計算結果がJavaScriptの Number.MAX_SAFE_INTEGER を超える可能性があり
、精度問題を引き起こす可能性があります。しかし、一般的な配列のサイズでは、これは通常問題になりません。
全体として、非常にクリーンで効率的な実装です。提案はあくまでコードスタイルの好みに関するもので、現在のコードでも十分
に機能します。
for...ofやreduceを使うような提案がありました。
今回はreduceを反映するようにお願いしてみます。
reduceの使用を反映して
✦ はい、承知いたしました。reduce メソッドを使用して findMissingNumberSum.ts を更新します。
╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ ? Edit findMissingNumberSum.ts: let actualSum = 0;... => const actualSum = arr.reduce... ← │
│ │
│ 7 │
│ 8 const expectedSum = (n * (n + 1)) / 2; │
│ 9 │
│ 10 - let actualSum = 0; │
│ 11 - for (let i = 0; i < arr.length; i++) { │
│ 12 - actualSum += arr[i]; │
│ 13 - } │
│ 10 + const actualSum = arr.reduce((sum, num) => sum + num, 0); │
│ 11 │
│ 12 return expectedSum - actualSum; │
│ 13 }; │
│ │
│ Apply this change? │
│ │
│ ● Yes, allow once │
│ ○ Yes, allow always │
│ ○ Modify with external editor │
│ ○ No (esc) │
│ │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
⠏ Waiting for user confirmation...
「Apply this change?(この変更を適用しますか?)」と表示されるので、
「Yes, allow once(はい、今回のみ許可します)」を選択します。
✦ findMissingNumberSum.ts を reduce メソッドを使用するように更新しました。
更新が完了しました。ファイルを確認すると、きちんと更新されていました。CLI操作だけでコードレビューが完結したのは驚きです。
/**
* 1からNまでの数値が格納された配列から、欠落している1つの数値を検索します。
* 配列はユニークな数値を含み、1つの数値のみが欠落していると仮定します。
*/
export const findMissingNumberSum = (arr: number[]): number => {
const n = arr.length + 1;
const expectedSum = (n * (n + 1)) / 2;
const actualSum = arr.reduce((sum, num) => sum + num, 0);
return expectedSum - actualSum;
};
まとめ
今回、Gemini CLIを使ってコードレビューからコード修正までの一連の作業を体験しました。
単にコードの改善点を指摘するだけでなく、具体的な修正案を提示し、さらにその修正をCLI上で直接適用できる点が非常に強力だと感じました。
最後に
GoQSystemでは一緒に働いてくれる仲間を募集中です!
ご興味がある方は以下リンクよりご確認ください。