目次
はじめに
こんにちは、いっちゃんです。10ANTZでは、サーバーサイドのソフトウェア開発に携わっています。また、趣味の一つに競技プログラミングがあり、週末の夜はAtCoder社のコンテストで問題を解くことを楽しんでいます。
本記事では、2023年1月16日に開催された社内勉強会について振り返ります。10ANTZのエンジニアの間では不定期で勉強会が開催されており、業務と直接関係あるかどうかに関わらず幅広いテーマが取り上げられています。今回は、アルゴリズム実技演習と銘打ちまして、競技プログラミングコンテストを開催しました。
ここで扱う競技プログラミングとは、参加者が、出題された問題を解くことのできるプログラムを作成することを競う競技です。作成されたプログラムが正しいかどうかは、出題者により予め用意されたテストケースに基づいて、ジャッジサーバーが自動的に検証し、順位に反映されます。
以下では、コンテスト開催の経緯、参加状況、出題例、振り返りを示します。
コンテスト開催の経緯
私が友人と趣味で作成した問題が既にいくつかあったため、社内で競技プログラミングコンテストを開催したい旨を先輩に伝えたところ、すぐに日程が決まり開催できることとなりました。
コンテストで使用した問題は30問です。難易度は、易し目のものが25問、難し目のものが5問です。(ここで、易し目の問題、難し目の問題とは、それぞれAtCoder Beginner Contestの100点から300点まで、400点から500点までの問題と同程度の難易度となる想定で作成した問題です。)コンテスト時間は1時間でした。
コンテストでは、オンラインジャッジシステムとして以下のものを使用しました。
https://github.com/QingdaoU/OnlineJudge
参加状況
開催したコンテストの結果を以下に示します。
コンテストには、13名の方に参加していただけました。1時間のコンテスト時間の中で、全員が1問以上の問題を正答し、2問以上の問題に挑戦していただけました。また、最高点は200点となっております。
参加者は競技プログラミングを趣味としている者がおらず、また、10ANTZでこれまでよく使用されてきたプログラミング言語であるC#とPHPをジャッジサーバーが扱っていなかったこともあり、慣れない環境であったことと思います。それにもかかわらず、コンテストに参加して私の作成した問題に挑戦していただけたことは、非常にありがたいと感じています。
出題例
コンテストの雰囲気を感じることができるように、出題された問題のうちの3問を抜粋して以下に示します。
02 Naming rules
スコア:40点、実行時間:3000ms
Description
文字列Sが与えられます.Sを構成する文字はそれぞれ英小文字,英大文字または「-」(ハイフン)です.
以下の手順に従って作成される文字列Tを求めてください.
- Sに含まれる英大文字を全て英小文字に置換する.
- の先頭の文字を英大文字に置換する.
- Sに含まれる文字で「-」の直後にあるものを全て英大文字に置換する.
- に含まれる「-」を取り除き,取り除かれなかった文字を順番を変えずに連結したものをTとする.
ただし,この問題ではについて以下が保証されます.
- 隣り合った2つの文字についてそれらの両方が「-」であるということはない.
- 先頭の文字は「-」ではない.
Input
入力は1行からなり,行目はです.は文字以上1,000,000文字以下の文字列です.
Output
1行目にを出力してください.
04 Linear Transformation
スコア:30点、実行時間:1000ms
Description
3個の整数A,B,が与えられます.
関数fを以下のように定義します.
- f(x) = Ax^B + C
が以下の条件を両方とも満たすかどうかを判定してください.
- 任意の実数,に対して,が成り立つ.
- 任意の実数,に対して,が成り立つ.
Input
入力は1行で,1行目は,空白で区切られた3つの整数A(),(),()からなります.
Output
1行目に,fが条件を両方とも満たすなら「Yes」,そうでないなら「No」を出力してください.
05 Numbers
スコア:20点、実行時間:2000ms
Description
整数が与えられます.
整数の列が与えられます.の番目()の要素はA_iです.
には何種類の整数が含まれるか求めてください.
Input
入力は2行からなります.
1行目は,1つの整数()です.
2行目は,空白で区切られた個の整数からなり,左から番目()の整数はA_i()です.
Output
1行目に,には何種類の整数が含まれるかを出力してください.
振り返り
コンテストは個人戦で、各々がコーディングに集中していたため、ワイワイと盛り上がることはありませんでした。それでも、黙々と集中して取り組んでもらえたようで、コンテスト後に参加者から「楽しかった」、「たまにはこういうのも良い」といったポジティブな反応もありました。そのため、開催して良かったと思いましたし、次回も開催したいと思いました。
次回コンテストを開催する場合に改善したい点の一つとして、標準入力のサポートが挙げられます。標準入力から入力を受け取る処理は、競技プログラミングで入力を受け取るため欠かせないものです。しかしながら、業務で使用する機会が少なく、プログラミング言語毎に標準ライブラリの使用方法が異なるため、競技プログラミングに慣れていない参加者にはハードルが高かったように見えます。次に社内で競技プログラミングコンテストを開催するときには、例えば、標準入力について解説している記事のURLをコンテストトップページに掲載したり、問題文中にヒントとして標準入力から入力を受け取るコードの例を掲載したりすることにより、標準入力で詰まることがないようにしたいと思います。
改善したい点の二つ目として、ローカル実行環境のサポートが挙げられます。オンラインジャッジシステムではランタイムエラーのエラーメッセージやテストケースの内容、プログラムが出力した内容を確認することができません。そのため、デバッグはローカル環境の方が行いやすいはずです。しかしながら、普段業務で使用しないプログラミング言語の実行環境をローカルに整えるのは簡単とは限りません。実際、コンパイルエラーとジャッジされたコードがいくつか提出されており、これらはローカル実行環境でコンパイルしていれば、提出前に気がつくことができたはずだと思います。次に社内で競技プログラミングコンテストを開催するときには、例えば、オンラインジャッジシステムがサポートしているプログラミング言語について、Dockerイメージを用意しておいたり、社内で使用されているmacOSにインストールされているプログラミング言語の実行方法をコンテストトップページに掲載したりすることにより、ローカル実行環境でのデバッグを行いやすくしたいと思います。
まとめ
まとめは以下の通りです。
- 社内で、アルゴリズム実技演習と銘打って競技プログラミングコンテストを開催しました。
- 13名の方に参加していただき、ポジティブな感想を得ることができました。
- コンテストの雰囲気を感じていただけるように、出題された問題を抜粋して示しました。
- 改善点として、競技プログラミングに慣れていない参加者のために、以下を実施することが挙げられました。
- 標準入力のサポート
- ローカル実行環境のサポート
社内にはまだ競技プログラミングが浸透していないように思われます。私としては、今後も競技プログラミングコンテストを開催して社内にその楽しさ伝えていきたいと考えております。