🐡

【コピペで試せる】Google Gemini を競技プログラミング学習の頼れる壁打ち相手にするプロンプト集(試行錯誤中!)

に公開

はじめに

競プロ学習、一緒に頑張りませんか? こんな悩み、ありますよね…

こんにちは! 競技プログラミング(競プロ)で中級レベル(例えば AtCoder で水色くらい?)を目指して、日々奮闘している(そして時々沼にはまっている…)学習仲間の一人です。皆さんも、こんな悩みを抱えながら学習を進めていませんか?

  • 「自分のレベルに合う問題を探すのが大変…」
  • 「この問題、どのアルゴリズムを使えば解けるんだろう…?」
  • 「解説を読んでも『???』となる部分があって、そこで手が止まっちゃう…」
  • 「解法の方針は立った気がするけど、本当にこれで合ってるか自信がない…」

特に一人で学習していると、こういう壁にぶつかって先に進めなくなったり、モチベーションが下がってしまったりしますよね。私もそうです。

AIが学習の「壁打ち相手」になってくれるかも?

そんな中、最近注目されている生成AI、特に Google Gemini のようなツールが、私たちの学習をサポートしてくれるかもしれない、と感じています。まだ私自身も試行錯誤の真っ最中ですが、特に 解法を考える上での「壁打ち相手」 として、うまく使えば非常に役立つ可能性があると感じています。例えば、

  • 自分のレベルや目的に合った練習問題を提案してくれたり
  • 分からないアルゴリズムの概念を、自分の言葉で質問したら答えてくれたり
  • 問題に対する解法アプローチのヒントをくれたり
  • 自分の考えた方針について、客観的な意見(?)をくれたり

といった手助けをしてくれる可能性を秘めているんです。(コードレビューやデバッグ支援もできるようですが、私自身はまだそちらはあまり試せていません。)

この記事では、私自身が特に 「解法発見の演習」 の中で「これは便利かも!」と感じた 具体的なプロンプト(AIへの指示文) を中心に、Google Gemini を競プロ学習に活用する方法をハンズオン形式で共有したいと思います。私もまだ完璧に使いこなせているわけではありませんが、皆さんと一緒に試しながら、AI アシスト学習の可能性を探っていけたら嬉しいです! コピペして試せるプロンプトをいくつか用意したので、ぜひ気軽に試してみてください。

この記事で共有したいこと

  • Google Gemini を使って競プロの練習問題を生成してもらうためのプロンプト例
  • 考えた解法を深掘りするために AI と対話する(壁打ちする)ためのプロンプト例
  • これらのプロンプトを試してみる上での、私なりのヒントや考え方

こんな方と一緒に試してみたい!

  • 競技プログラミング学習者の方(特に、私と同じように初心者〜中級レベルで、解法を考える部分で悩むことが多い方)
  • Google Gemini などの生成 AI をプログラミング学習(特に思考の補助)にどう活かせるか、試してみたい方

主に Google Gemini で試した例を紹介しますが、プロンプトの考え方は ChatGPT (GPT-4) など他の AI でも応用できると思いますので、ぜひ皆さんの環境でも試してみてください。

必要なもの

  • Google アカウント: Google Gemini を利用するために必要です。
    • (補足)Web ブラウザから無料で利用できます。特別な設定は不要です。

準備: Gemini と「いい感じ」に対話するために

Gemini の基本的な使い方はご存知かと思いますので、ここでは AI に意図を伝えやすくするための、プロンプトに関する一般的な考え方について少し触れておきます。AI との対話をよりスムーズにするヒントになるかもしれません。

一般的に、以下のような要素をプロンプトに含めると、AI が意図を理解しやすくなると言われています。

  • 役割 (Role): AI に特定の専門家やキャラクターになりきってもらうことで、回答の視点を定めやすくする方法です。(例: 「あなたは経験豊富な競技プログラマーとして答えてください」)
  • 指示 (Instruction): AI に具体的に何をしてほしいかを明確に伝えます。(例: 「以下の条件で問題を作成してください」)
  • 制約 (Constraints) / 条件 (Conditions) / 文脈 (Context): 指示を補足する情報や、守ってほしいルールを与えます。(例: 「難易度は〇〇レベル」「出力形式は〇〇」)

【重要】コンテスト中の AI 利用に関する注意

競技プログラミングコンテストの多くでは、コンテスト開催中に、そのコンテストの問題文(またはそれに準ずる固有の情報)を直接 AI に入力し、解法、ヒント、コードなどを生成させる行為は、外部の助けを借りて問題を解くことに相当するため、ルール違反とみなされる可能性が高いです。失格やアカウント停止などのペナルティに繋がる恐れがあるため、このような使い方は避けるべきでしょう。

一方で、一般的なアルゴリズムの概念(例えば「ダイクストラ法とは何か?」)、特定のプログラミング言語の文法、過去に公開された問題の一般的な解法テクニックなどについて、学習目的で AI に質問することは、通常問題視されないと考えられます。 これは、技術書を読んだり、Webで調べたりするのと同じ学習活動の一環とみなされることが多いでしょう。

この記事で紹介する AI への質問テクニックは、皆さんの 日々の学習や、コンテスト以外の場でのスキルアップ のために活用してください。コンテストに参加される際は、必ずそのコンテストの公式ルールや FAQ をご自身でよく確認し、その指示に従うようにしましょう。 AI の利用に関する規定はコンテストによって異なる可能性があるため、事前の確認が非常に重要です。

【補足】プロンプトの「書き方」について:構造化 vs 自然な会話

この記事で後ほど紹介するプロンプト例の中には、説明のために、上記のような役割や指示などを「# Role:」のように構造化して記述しているものがあります。これは AI に意図を正確に伝えるための一つの方法として、特に複雑な指示を出す場合に有効な場合があるようです。

ただ、正直なところ、私自身は普段、もっと短い、普段話すような自然な言葉で Gemini と対話することがほとんどです。 特に会話が続いている状況では、それで十分意図が通じることが多いと感じています。「今の問題のヒント教えて」とか「DPで解ける?」みたいに聞く感じです。

一方で、AI がこちらの意図をうまく汲み取ってくれなかったり、期待と違う答えが返ってきたりした場合には、上記のような要素を意識して、少し詳しく指示を書き直してみると改善することがあるかもしれません。

結論としては、必ずしも構造化された詳細なプロンプトが良いというわけではなく、状況に応じて使い分けるのが良さそうです。 私も含め、皆さんも色々な書き方を試して、自分にとって自然で、かつ AI に意図が伝わりやすいスタイルを見つけていくのが良いのかなと思います。この記事の構造化されたプロンプト例は、あくまで「こういう書き方もある」という参考程度に見ていただければと思います。

それでは、具体的なハンズオンに進みましょう!

ハンズオン1: 自分だけの練習問題を作ってもらう

「特定のアルゴリズムを集中的に練習したい」「今の自分に合った難易度の問題が欲しい」そんな時に、AI に問題を作ってもらうのを試してみましょう。新しい問題に触れる良い機会になります。

  • 目的: 特定の分野や難易度の問題を生成してもらう

  • プロンプト例: まずはこんな感じで聞いてみましょう。もっと自然な言葉で「DPの簡単な練習問題作って!」みたいにお願いしても大丈夫です。参考までに、少し構造化した書き方の例も載せておきますね。

    (自然な言葉での例)

    競技プログラミングの練習問題を作ってください。
    テーマは「動的計画法(DP)の導入」で、難易度はAtCoder Beginner ContestのC問題くらい。
    配列の要素を選ぶような問題がいいです。
    問題文、制約、入力形式、出力形式、入力例と出力例を1つずつお願いします。
    制約は N<=100, a_i<=1000 くらいで。
    

    (構造化した書き方の例)

    # Role: 競技プログラミングの問題作成者
    # Instruction: 以下の条件で問題を作成してください。
    # Conditions:
    - 難易度: AtCoder Beginner Contest の C 問題レベル
    - テーマ: 動的計画法 (DP) の導入
    - 題材: 配列の要素選択
    - 出力形式: 問題文、制約、入力形式、出力形式、入力例1, 出力例1
    # Constraints:
    - N <= 100
    - a_i <= 1000
    
  • 解説: この例では、AIに問題作成をお願いし、欲しい問題の条件(難易度、テーマ、題材など)を伝えています。

  • 実行結果のイメージ: うまくいけば、Gemini が指定に沿ったオリジナルの問題文や制約、入出力例などを提案してくれるはずです。(※AIによる生成内容は毎回異なり、質にばらつきがある可能性もあります!)

  • 試してみよう!: 問題が生成されたら、条件を変えて色々リクエストしてみましょう!「難易度をD問題にして」「グラフ問題で」「入力例3つ欲しい」など、自由にお願いしてみてください。

生成された問題について対話してみる

さて、問題が生成されたら、その問題について Gemini と対話を続けてみましょう。同じチャットセッション内で続けるのがポイントです。これにより、Gemini は直前の文脈(生成した問題)を理解した上で応答してくれます。

  • 目的: AI が生成した問題の解法アプローチ、考え方のヒント、別解や難易度感などを、対話を通じて得る。

  • 対話例:

    (Gemini が問題を生成した後、同じチャットで続けて)
    
    あなた: ありがとう!今作ってくれた問題、面白そうですね。この問題を解くための考え方の方針について、いくつかヒントをもらえますか? どのアルゴリズムを使うのが良さそうでしょうか?
    
    Gemini: (回答例)この問題は動的計画法(DP)で解くのが典型的ですね。配列の要素を左から順番に見ていき、「その要素を選ぶか、選ばないか」を考えながら、そこまでの最大値を記録していく、といった方針が考えられます。
    
    あなた: なるほど、DPですか。状態定義は `dp[i] = i番目までの要素を見たときの最大値` みたいに考えれば良いですか? ちょっと自信がないです。
    
    Gemini: (回答例)良い着眼点ですが、その状態定義だと「i番目の要素を選んだかどうか」の情報が足りないため、次の遷移(i+1番目をどうするか)を正しく計算するのが難しいかもしれません。例えば、`dp[i][0]` を「i番目まで見て、i番目の要素を選ばなかった場合の最大値」、`dp[i][1]` を「i番目まで見て、i番目の要素を選んだ場合の最大値」のように、2つの状態を持たせるのはどうでしょうか?
    
    あなた: あ、なるほど!それなら遷移できそうです。ありがとう!
    
    (さらに続けて、別解や難易度についても聞いてみる)
    
    あなた: ちなみに、この問題、**DP以外の解法(別解)はありますか?**
    
    Gemini: (回答例)そうですね、この問題の制約であればDPが一般的ですが、例えば要素が全て正であれば貪欲法に近い考え方も一部適用できるかもしれませんが、最適解が得られる保証はありません。基本的にはDPが推奨されます。
    
    あなた: なるほど、ありがとうございます。ちなみに、この問題の**難易度はAtCoderだとどのくらいのレベル(ABCのA, B, C, Dなど)だと思いますか?**
    
    Gemini: (回答例)この問題設定と制約であれば、典型的なDPの導入問題として、AtCoder Beginner ContestのC問題レベルに相当すると考えられます。
    
  • 学習への活用:

    • このように、生成された問題についてすぐに対話を始めることで、問題の理解を深めたり、解法の糸口を掴んだりする練習ができます。
    • 「ヒントをください」「この考え方で合ってる?」「もう少し詳しく教えて」のように、自然な言葉で対話を進められるのが AI アシストの便利な点だと感じています。
    • さらに、生成された問題について**「別解はありますか?」と尋ねてみたり、「この問題の難易度は、AtCoderでいうとどのくらいだと思いますか?」**と聞いてみるのも、理解を深める上で非常に有用だと感じています。複数の解法を知ることでアルゴリズムの適用範囲の理解が広がりますし、難易度感を掴むことで自分の現在地を確認する目安にもなります。(もちろん、AIの評価や提案が常に正しいとは限りませんが!)

【注意】 ここでの相談は、あくまで 自分が学習用に生成した問題や、既に公開されている過去問 に対して試しているものです。コンテスト開催中に未公開の問題について同様の行為を行うのはルール違反とみなされる可能性が高いのでご注意ください。(詳細は「準備」セクションの注意喚起を参照してください。)

ハンズオン2: 解法のアイデアを深掘りする(壁打ち)

ハンズオン1の流れで問題の方針がある程度見えてきた後、「この方針で本当に大丈夫かな?」「もっと効率的な方法はないかな?」「コーナーケースはどうだろう?」と、さらに考えを深めたい時がありますよね。そんな時に、AI を考察の壁打ち相手として使ってみるのも面白いかもしれません。これも同じチャットセッション内で続けると、前の会話を踏まえた応答が期待できます。

  • 目的: 自分の考えた解法を検証・改善するためのヒントや、別の視点を得る。

  • 対話例:

    (ハンズオン1の「配列の選択」問題で、DPの方針と状態定義 `dp[i][0]`, `dp[i][1]` が見えた後の対話を想定)
    
    あなた: さっきのDPの状態定義 `dp[i][0]`(iを選ばない最大値)と `dp[i][1]`(iを選ぶ最大値)についてですが、**遷移式**は具体的にどう書けばいいですか? `dp[i][1]` を計算するには `dp[i-1][0]` を使いますか?
    
    Gemini: (回答例)その通りです。`dp[i][1]`(i番目を選ぶ場合)を計算するには、i-1番目は選べないので `dp[i-1][0]` を使う必要があります。遷移式は `dp[i][1] = dp[i-1][0] + A[i]` のようになりますね。一方、`dp[i][0]`(i番目を選ばない場合)はどう計算できると思いますか?
    
    あなた: `dp[i][0]` は、i-1番目を選んでも選ばなくても良いので、`dp[i-1][0]` と `dp[i-1][1]` の大きい方を取ればいいですか? つまり `dp[i][0] = max(dp[i-1][0], dp[i-1][1])` でしょうか。
    
    Gemini: (回答例)その考え方で合っています!素晴らしいですね。これでDPの遷移式が完成しました。
    
    あなた: よかった!このDPだと、ループは N 回なので**計算量**は O(N) で済みそうですね。制約が N <= 100 なので十分間に合いそうです。何か**見落としやすいコーナーケース**はありますか? 例えば N=1 の場合はどうなりますか?
    
    Gemini: (回答例)計算量は O(N) で良さそうです。コーナーケースとしては、おっしゃる通り N=1 の場合や、配列の要素が全て負の場合なども考慮すると良いかもしれません。N=1 の場合は、`dp[1][1] = A[1]`, `dp[1][0]` は初期値(例えば0)となり、最終的な答えは `max(dp[1][0], dp[1][1])` ですね。ただし、要素が全て負の場合は...(解説が続く)
    
  • 学習への活用:

    • このように、方針が決まった後も、状態定義、遷移、計算量、コーナーケースなど、考察の各段階で AI と対話することで、自分の考えを整理し、見落としを防ぐ助けになるかもしれません。
    • 「なぜそうなるの?」「他に方法は?」「もし制約がこうだったら?」のように、さらに質問を重ねることで、より深い理解に繋がることもあります。
  • 試してみよう!: あなたが今考察中の問題について、考えた解法や疑問点を Gemini にぶつけてみませんか? まるで勉強仲間と議論するように対話してみると、新しい視点や気づきが得られるかもしれません。AI の提案が常に正しいとは限りませんが、自分の思考を整理したり、別の可能性を探ったりする良いきっかけになることがあります。

(発展)Gem 機能で「マイメンター」を作る

毎回「あなたは競プロメンターです…」といったプロンプトを入力するの、ちょっと面倒ですよね。私もそう感じていました。そんな時、Gemini の Gem 機能 が便利かもしれません。これは、特定の役割や指示を「マイAI」として保存しておける機能です。

例えばこんな感じで設定しておくと、

競技プログラミングメンターとして、AtCoder Dレベルの問題を作成して出題してください。出題時には解説・ヒントは含めないでください。

Gemini の画面からこの「競プロメンター Gem」を選ぶだけで、いつでも設定した役割として応答してくれるようになります。プロンプト入力の手間が省けて、個人的にはかなり学習がスムーズになりました。興味があれば試してみてください。

まとめ: AI と一緒に、試行錯誤しながら学んでいこう!

今回は、Google Gemini を競技プログラミング学習、特に 解法を考える上での壁打ち相手 として活用するための具体的なプロンプトについて、私自身の試行錯誤を交えながら共有させていただきました。

私自身、AI を使うことで、アルゴリズムの理解が深まったり、解法の引き出しが増えたり、考察の方向性を修正できたり といったメリットを感じています。(もちろん、AI が見当違いなことを言うことも多々ありますが…笑)

AIとの対話で意識していること(試行錯誤中):

私自身、まだ最適な対話方法を模索中ですが、今のところ以下のような点を意識すると、うまくいくことが多いように感じています。

  • 具体的に聞く: 曖昧な質問より、具体的に何を知りたいか伝える。
  • 自分の考えも伝える: 「〇〇と考えているけど合ってる?」のように、自分の思考プロセスも示すと、より深い議論になりやすい気がします。
  • 段階的に進める: 一度に全部聞くのではなく、対話を重ねながら少しずつ掘り下げていく。
  • 色々試してみる: 同じ指示でも、聞き方を変えると応答が変わることも。めげずに色々試すのが大事かもしれません。
  • (プロンプトの書き方について)この記事では構造化された例も紹介しましたが、私は自然な会話形式で進めるのが今のところ好みです。どちらが良いかは状況によると思います。

AI と学習する上での心構え(自戒も込めて):

  • 鵜呑みにしない: AI の言うことが常に正しいとは限りません。必ず自分で考え、検証する姿勢が大切だと痛感しています。
  • 思考停止しない: AI に頼りすぎず、自分で粘り強く考える時間も大事にしたいですね。
  • ルールを確認・遵守する: コンテスト本番で問題文を AI に入力するなどの行為は、多くのコンテストで公平性の観点から問題視され、ルール違反と判断される可能性があります。学習目的での利用に留め、参加するコンテストの規約は必ず事前にご自身で確認することが不可欠です。 (詳細は「準備」セクションの注意喚起も参照してください。)

もっと知りたい方へ:

私のブログでは、AI を活用した競プロ学習(特に解法考察のプロセス)に関する試行錯誤の記録や、AI が作った問題の考察などをマイペースに発信しています。もしよろしければ、覗いてみてください。

この記事が、皆さんと同じように競プロ学習を頑張っている方にとって、何か少しでもヒントや試してみるきっかけになれば、とても嬉しいです。AI という新しいツールとも上手に付き合いながら、一緒に楽しくスキルアップしていきましょう!

Discussion