Arrow Judgeをインストールして社内プログラミングコンテストを開催する


1. はじめに

社内に競技プログラミング部を作ってはどうだろう。互いに問題を投稿し合い、切磋琢磨していくような環境にならないだろうか...。そんなことを漠然と考えていると、タイミング良く「社内イベントを企画せよ」との指示が。というわけで、競技プログラミング形式でのプログラミングコンテストを、思い切って開催してみることにしました。

2. どうやったか

そのようなシステムってどうやって作るのだろう?と検索していると、以下の資料にたどり着きました。

目を通していて胸が熱くなりました。

  • オンラインジャッジシステムを簡単にホスティングできる
  • ユーザが自由に問題を追加できる
  • クローズドなコンテストも開催できる
  • 入力可能なプログラミング言語を追加できる

求めていたシステムがすでに提供されている!しかもオープンソースで!早速インストールして数人で利用してみると、反応は上々。これはいけそうだ。(長くなるので、Arrow Judgeのインストール手順は後述します)

3. どうなったか

数ヶ月のテスト運用の後、実際に社内プログラミングコンテストを開催してみました。

  • 業務終わりの時間に開始したにもかかわらず、開発者の半数近くが参加した
  • 最終的に、参加者全員が全問に解答した(未解答問題が残った人は、終了時間を過ぎてもチャレンジを続けた)
  • 実施後に他の人の解答(ソースコード)を参照することで、技術的なコミュニケーションが生まれた
  • アンケートには以下の声
    • 競技プログラミング形式でのプログラミングコンテストは良かった
    • 参加して良かった 再度開催されたらまた参加したい

そこには、問題を解くたびに達成感が得られ、さらに夢中になって取り組むという好循環がありました。また、開発者同士が相互に気づきを与え合う、学びの場となっている実感を得られました。

それからしばらく経ちましたが、実はまだ、競技プログラミング部の設立には至っていません。結局のところ、問題の良し悪しが成功の鍵を握るので、コンテストの問題を考えることがネックとなりました。

そこで、現在はProject Eulerの利用を考えています。すでにProject Eulerの問題を解いている開発者もいるので、コンテストを開催することはできませんが、Arrow Judgeにはコンテストだけでなく、常時、掲載された問題へ解答を投稿できる機能もあります。そこへProject Eulerの問題を掲載しておくことで、新入社員の研修、アルゴリズムの学習、他プログラミング言語の習得などに活用していくことができそうだと考えています。

以下、Arrow Judgeの参考画面です。

問題一覧

問題

解答(ソースコード)入力

評価結果一覧

4. インストール

ここからはArrow Judgeのインストール手順などを書いていきます。

サーバ環境はUbuntu 12.04 LTS Desktop 日本語 Remixを利用しました(記事の最後に、Ubuntu14.04へのインストールについても追記しました)。また、IPアドレスは 192.168.2.10 であるとしています。

※Linux関連の知識はほとんどなく、検索しながら進めた内容になります。最適でない可能性がありますので、間違いなどありましたら、お知らせいただけると嬉しいです。

4.1. 事前準備

リポジトリの追加

Arrow Judgeをapt-getでインストールできるよう、リポジトリを追加しておきます。

$ sudo apt-add-repository ppa:hiromu1996/arrow-judge
$ sudo apt-get update

4.2. Webサーバの準備

arrow-judge-webのインストール

まず、Arrow JudgeのWebサーバ機能1を担う、arrow-judge-webのインストールを行っていきます。arrow-judge-webの動作にはApache、MySQL、PHPが必要となるので、LAMPサーバーをインストールします。

$ sudo apt-get install tasksel
$ sudo tasksel install lamp-server

その後、arrow-judge-webをインストールします。

$ sudo apt-get install arrow-judge-web

データベースの準備

続いて、ユーザ情報や問題などを管理するデータベースを作成します。MySQLへrootでログインし、データベース名、ユーザ名、ユーザパスワードなどを指定します。(以下の例では、データベース名:arrow_judge、ユーザ名:judge、ユーザパスワード:xxxxとしていますが、適宜変更して構いません)

$ mysql -u root -p
> CREATE DATABASE arrow_judge DEFAULT CHARACTER SET utf8;
> CREATE USER 'judge'@'localhost' IDENTIFIED BY 'xxxx';
> GRANT ALL PRIVILEGES ON arrow_judge.* TO 'judge'@'localhost';
> FLUSH PRIVILEGES;
> quit

また、インストールされたデータベースの初期化スクリプトを修正しておきます。/usr/share/arrow-judge/app/Config/database.sql 内の以下の部分で`users`を`testcases`へ変更します。

database.sql.diff
--- database.sql    (revision x)
+++ database.sql    (working copy)
@@ -331,8 +331,8 @@
 --

 LOCK TABLES `testcases` WRITE;
-/*!40000 ALTER TABLE `users` DISABLE KEYS */;
-/*!40000 ALTER TABLE `users` ENABLE KEYS */;
+/*!40000 ALTER TABLE `testcases` DISABLE KEYS */;
+/*!40000 ALTER TABLE `testcases` ENABLE KEYS */;
 UNLOCK TABLES;

 --

arrow-judge-webの設定

ここからは、ブラウザを利用しての設定となります。

ディレクトリ所有権

ブラウザから http://192.168.2.10/judge/ へアクセスし、表示された各ディレクトリの所有者をsudo chown -hR www-dataで変更します。

$ sudo chown -hR www-data /usr/share/arrow-judge/app/Data/Answer/
$ sudo chown -hR www-data /usr/share/arrow-judge/app/Data/Output/
$ sudo chown -hR www-data /usr/share/arrow-judge/app/Data/Testcase/
$ sudo chown -hR www-data /usr/share/arrow-judge/app/tmp/
$ sudo chown -hR www-data /usr/share/arrow-judge/app/Plugin/HtmlPurifier/Vendor/HtmlPurifier/library/HTMLPurifier/DefinitionCache/Serializer

その後「Recheck」を押すと、ボタン名が「Install」に変化し、以下のようになります。

これ以降も、ブラウザに表示された指示に従い、先に作成したデータベース情報や、SMTPサーバ情報などを入力していけばOKです。

データベース

SMTPサーバ

管理者アカウント

トップページ表示内容

4.3. ジャッジサーバの準備

arrow-judgeのインストール

次は、ジャッジサーバ機能2を担う、arrow-judgeをインストールします。本来は、複数のサーバへインストールし、分散処理できるようになっているのですが、簡単のためWebサーバと同一環境へインストールしました。

$ sudo apt-get install arrow-judge

途中でWebサーバのURL入力が必要となるので、http://192.168.2.10/judge と指定します(最後に/をつけない)。

ジャッジサーバの有効化

インストールが完了するとWebサーバから認識されます。先ほど設定した管理者アカウントでWebサーバへログインし、上部に表示されている「Site Config」からジャッジサーバを有効化します(Enableをクリック)。

x86対応

利用した環境が32bitだったので、スクリプトの修正が必要でした。

$ sudo /etc/init.d/arrow-judge stop

で、arrow-judgeを停止してから、/usr/lib/python2.7/dist-packeges/arrow-judge/__init__.py 内の以下の部分で'/lib64'を削除し、

__init__.py.diff
--- __init__.py (revision x)
+++ __init__.py (working copy)
@@ -2,5 +2,5 @@

 AVAILABLE_DEVICES = ['full', 'null', 'random', 'stderr', 'stdin', 'stdout', 'urandom', 'zero']
 CGROUP_SUBSETS = ['cpuacct', 'memory']
-AVAILABLE_PATHS = ['/bin', '/etc', '/lib', '/lib64', '/proc', '/sbin', '/usr/bin', '/usr/include', '/usr/lib', '/var/lib']
+AVAILABLE_PATHS = ['/bin', '/etc', '/lib', '/proc', '/sbin', '/usr/bin', '/usr/include', '/usr/lib', '/var/lib']
 SYSCTL_PARAMS = ['kernel.sem=0 0 0 0', 'kernel.shmall=0', 'kernel.shmmax=0', 'kernel.shmmni=0', 'kernel.msgmax=0', 'kernel.msgmnb=0', 'kernel.msgmni=0', 'fs.mqueue.queues_max=0']

再度、arrow-judgeを起動します。

$ sudo /etc/init.d/arrow-judge start

コンパイラの追加

Webサーバへ解答(ソースコード)を投稿する際、初期設定では C(gcc)、C++(g++)が選択できるようになっています。どちらも利用できるようにするため、ジャッジサーバへg++をインストールしておきます。

$ sudo apt-get install g++

以上で、準備は完了です。問題を作成し、プログラミングコンテストライフをお楽しみください。

5. 運用

5.1. arrow-judgeの起動、停止

起動と停止は以下で行えます。

$ sudo /etc/init.d/arrow-judge start
$ sudo /etc/init.d/arrow-judge stop

起動後、/var/log/arrow-judge/judge.logに

started with pid xxx

と表示されていない場合は正常に起動していないので、起動後に確認すると良いと思います。

5.2. arrow-judgeの設定

設定ファイルは/etc/arrow-judge/server.confにあります。

6. 注意

作成したコンテストは削除できないようです。また、公開後のコンテストへは問題を追加できないようです。

7. Ubuntu14.04へのインストール

Ubuntu 14.04 LTS 日本語 Remixへのインストールをトライしてみました。上記の手順と異なる部分を記載します。

7.1. arrow-judge-web

Apacheの設定

http://192.168.2.10/judge/ でArrow Judgeへアクセスできるよう、エイリアスの設定が必要です。(Ubuntu12.04ではconf.dディレクトリが存在していたので、インストール時に自動的に行われていました)

$ sudo cp /etc/arrow-judge/apache.conf /etc/apache2/conf-available/arrow-judge.conf
$ sudo a2enconf arrow-judge
$ sudo service apache2 reload

CakePHPテンプレートを修正

/usr/share/arrow-judge/app/View 以下にあるCakePHPテンプレートファイルを、いくつか修正する必要があります。すでにPull requestされていますので、以下を参照して対応(「<?」を「<?php」へ変更)してください。(Ubuntu12.04ではとくに対応しなくても問題ありませんでした)

Use long tags in PHP #4
Use long tags in PHP #5

7.2. arrow-judge

64bit環境を利用する場合、上記x86対応は不要です。


  1. 問題の掲載、解答(ソースコード)の投稿、評価結果(正解/不正解)の表示などを行う 

  2. 投稿された解答(ソースコード)のコンパイルと実行、実行結果の評価などを行う