interprism's blog

インタープリズム株式会社の開発者ブログです。

社内プログラミングコンテスト(もう一つの視点から)

背景はよく覚えていないが、プログラミングコンテストを開催することとなった。 初めての試みでどれ位のエントリーがあるが不安だったが、とりあえずやってみることにした。 問題を作成するにあたって、以下の3点に気をつけた。

  1. 問題をみてやる気を失わないように、極めてわかりやすい問題であること
  2. 新入社員を含めより多くのプログラマが参加できるように、単純なAPIだけで処理できること
  3. 知識勝負ではなく、知恵で勝負できるように、Webで調べて定石等が見つからないような問題であること

言語は当社のエンジニア全員が扱えるようJava言語を採用した。

今回の問題は以下のようなものである。

「問題ファイル 内に書かれている計算式の要素を 入力ファイルから読み取り、計算結果をファイルに出力するプログラムを書いてください。 計算結果は各行に計算結果のみを出力してください。」

というもの。 入力ファイルは

1,5,3
2,8,1
9,2,6

というように、正の整数を要素とする正方行列であり 問題ファイルが

[0,1]+[2,2]=
[2,0]+[1,1]=

というように、入力ファイルの要素通しの足し算を列挙している これらの入力に対して

11
17

というファイルを出力することを要求されている 今回のコンテストではこの処理を如何に短時間で行えるプログラムを作成できるかを競う。

問題は社内のサイトにエクリプスのプロジェクトフォルダをzipで固めた形でアップロードされており、 そのzipを解凍して、エクリプスにプロジェクトとしてインポートして、 テンプレートパターンになっているメソッドを実装するとすぐさま実行することができるようになっている。

当社役員のH野氏が問題を作成し、H野氏の指示のもとG藤氏がソースコードをアップロードすると、自動でコンパイルし、実行し、スコアを計算し、結果とランキングを画面に出力するWebシステムをちょちょいのちょいと作ってくれた。

期間は約3週間。4月半ばから5月のゴールデンウィーク開けまでだ。

まず最初に投稿したのは、I本氏。社交性があり、明るく前向きで積極的な性格でもあるI本氏は、こういうイベントには率先して強力してくれる。タイムは6.980秒。このタイムが速いのか遅いのかはわからないが、一つの基準になるのは間違いない。

次に投稿してきたのは、システムをちょちょいのちょいと作ってくれたG藤氏。G藤氏はクールな性格で、クールに世の中の現象を眺めている。何事にもクールに取り組みたいG藤氏は、クールにコードを組んでクールに2ゲットしてきた。タイムは6.454秒。0.5秒上回ってトップに立った。

次に投稿してきたのは、優勝候補本命で役員でもあるA藤氏。A藤氏は変態なので、誰もが一目をおいている。ハードにも強く、粘着気質の性格も彼のプログラマーとしての能力を押し上げている。いきなり3秒近くタイムを縮め、3.648秒を記録し、「まあ、4秒が切れればまあまあじゃない」等、自分はまだまだタイムを縮められるという雰囲気を醸し出し、上から目線で、下々の成り行きを眺めている。その後2回の投稿で最速タイム3.194秒を叩きだした。

続いて、今回のコンテストの問題の作成者である運営の責任者でもある役員のH野氏が投稿してきた。問題出題者がコンテストに参加するのは、公平性の観点から問題があるような気もするが、まあ細かいことは気にしないでおこう。タイムは7.764と平凡だ。きっと、隠し玉を持っていて、最後にいっきに逆転してくるのでは、とも予想していたが、これ以後彼のエントリーはなかった。運営側として自粛したのか、これがベストなのかは、気にしないでおこう。

次に投稿してきたのは、4月に入社したばかりのN部氏。N部氏はバイオリンをこよなく愛しており、笑顔を常に絶やさない。プログラミング歴は大したことないものの、バイオリンで養った集中力により4.068秒の高タイムを叩き出し、新人でありながら、2位につけた。プログラミング経験の浅いN部氏が2位につけたことで、ある意味、問題作成の意図が有効に実現できていることが証明され、現在最下位についているものの、問題作成者のH野氏の能力が別の角度から評価されることとなった。

さらに、入社3年目のI藤氏が投稿してきた。タイムは4.477秒。平凡なタイムではあるが、大学院で並列コンピューティングを研究していたI藤氏は不気味な存在である。この後、タイムを縮めてくるのではと予想される。

さらに、ベテラン社員であるO澤氏も参戦してくれた。真面目で実直な性格であるO澤氏はコンテストのコードも着実であることが予想されるが、その性格のとおり7.250秒で確実に処理をするが、今回のコンテストはコードの可読性や不具合を起こしにくいコードであることが要求されているわけではない。可読性が悪かろうがなんだろうが、とにかく速ければよいのである。(もちろん、正解である必要はあるが)

次に、入社8年目のS根氏が参戦してきた。S根氏はコーディングが速いことで有名だ。しかし、こだわりが少ない彼は、正解を求めるという課題をすぐに解決はしたが、何度も言っているとおり、今回のコンテストはどんだけ時間をかけてコーディングをしてもよいので、プログラムがより短時間で動作することのみが求められている。S根氏のタイムは6.729秒。2時間後に5.990秒まで縮めたが、それ以後彼が投稿することはなかった。コーディングが速いS根氏は、引き際の意思決定も速いようだ。

概ね参加者が出揃ったように見えるが、一人厄介なものの投稿がまだない。社長のA木氏だ。彼は極度な負けず嫌いであり、かつ社長という役職的なものもあるため、また仮に役職的なものがなかったとしても、単純に人として扱いが面倒だ。ある程度の自信はあるようだが、それ以上に負けず嫌いであることを鑑みると、これだけの猛者が集まるコンテストで、例え1位に躍り出ても、すぐに記録が上書きされるであることは容易に想像できるため、締め切りギリギリで投稿して勝利をかっさらう作戦のようだ。

そんな中、クールなG藤氏が上げたコードが一つのきっかけをつくることになる。処理時間が1.624秒と大幅にタイムを縮めてトップに踊りでた。これには多少社内がザワザワしたが、本人の「もしかしたらルール違反をしているかもしれない」という言葉で調査をしたところ、やはりルール違反のコードであったことが判明した。今回のコンテストでは、MemoryMappedFileを使うことが禁止されているのだが、どうやら間接的にそれを使ってしまっていたということだった。一時はエントリーを削除したが、一つの目標になるということで、エントリー削除を取り消してもらった。

一つの目標ができたことで、記録が動き出す。

I本氏:6.078→5.239→5.214→4.477→4.355→4.013→3.695→3.603
N部氏:4.268→4.068→3.276
I藤氏:2.144→2.136

と縮めてきてついに並列コンピューティングのI藤氏が1秒台(1.666)のタイムに到達した

役員で変態のA藤氏もGW中に投稿を繰り返し、1秒台に突入し、ついにMemoryMappedFileを使わずに、1.317までタイムを縮めトップにたった。

そんな中、ついに社長で負けず嫌いのA木氏が締め切り最終日(正確には最終日の翌朝未明。従って締め切り後)に最初の投稿で1.520というタイムで2位に食い込んできた。そして、同日(締め切り後だが、エントリーができた)に

1.495→1.478→1.398→1.384→1.298

と1位の変態役員A藤氏に肉薄していく。これを見た変態役員A藤氏はトップであるにも関わらず更に

1.174→1.126→1.082→1.067→1.001

とタイムを縮め、ついには0.977と1秒を切るタイムを叩き出す。

翌朝、これを見た負けず嫌いの社長A木氏は、締め切りはとうの昔に過ぎているはずなのに、さらに

1.232→1.172→1.164→0.990→0.946→0.914

とタイムを縮めついにトップに踊りでた。

このきりのない不毛な戦いに、社員が気を利かせてくれて、ようやくここで、本当の締め切りでシステム的にエントリー(アップロード)をすることをできなくしてくれた。

ということで、表面的な結果をいうと

順位 名前 実行時間(ms)
1 負けず嫌い社長A木氏 914
2 変態粘着役員A藤氏 977
3 クールG藤氏(with禁止ライブラリ) 1624
4 並列コンピュータI藤氏 1666
5 バイオリンN部氏 3276
6 JS大好きI本氏 3603
7 クイックS根氏 5990
8 確実O澤氏 7250
9 主催者役員H野氏 7764

となった。 プログラミングの腕もさることながら、このコンテストに注ぎ込んだ実装時間と順位に相関関係があるように見えてしかたがない。

その何日か後、感想戦を行うことになった。 各参加者が、ソースコードを解説しながら、設計思想や実装方針を明らかにしていく。 そこで明らかになったのは、社長のA木氏と並列コンピュータのI本氏が、今回のコンテストで使われるデータの特性に依存したコードでタイムを縮めていたということだ。 これは、反則だという意見とセーフだという意見がかわされたが、みんな大人だし、特に今回の順位で報酬があるわけでもないので、特に白黒を付けるということはしなかった。

感想戦を経て学んだことは単純なAPIしか使わない単純な処理でも、競い合って、ギリギリまでチューニングしていこうとする過程の中で、VM上で動く高級言語でもあるJavaでも、CPUのキャシュ容量を気にしたり、如何にしてJITコンパイラが有効にきくようにするか等を意識せざるを得なくなり、通常の業務ではあまり考えない、従って通常の業務だけではあまり得ることができない知識を得ることができた。

非常に楽しかったので、今後も是非継続したいと思うが、こういうコンテストは問題を考えることが極めて難しい。そういう意味で、最下位ではあったが、問題を作ってくれたH野氏に尊敬と感謝の念を込めて、この文章を終えたい。

PAGE TOP