こちらもあわせてどうぞ。tryはじめに先日、FizzBuzz問題を使って社内プログラミングコンテストを開きました。このブログでも書いた通り、なかなか興味深い結果になりましたが、一方で反省点もいくつか見つかりました。問題が解けなかった人が出てしまったのは痛い誤算だったので、今回はできるだけ最後まで解けるような配慮をしてみました。問題自体はFizzBuzz問題よりもずっと難しくしてあります。今回もちょっと長いエントリになっていますが、よろしければ最後までお付き合いくださいませ。詳しくはこちらのエントリに書きましたが、簡単にまとめると言語の得意・不得意が結果に大きく影響した抜き打ちで実施したことがその影響をより大きくしたという2点に集約されます。前回の反省点を活かし、今回はコンテストのルールを以下のように変更してみました。開催日と使用言語を事前に通知する。開催日は約2週間前に通知。使用する言語をPerlに統一することも同時に通知。「基本構文と文字列関数が重要。ファイル操作は出題しない。」というように、予習項目もある程度通知。その代わり、「Perlが苦手なんで解けませんでした」はNGとする。予習しても実務経験の差は縮まらないので、解答の速さは評価しない。前回は速く解けた人にボーナスポイントを与えたが、今回は無し。問題は2問、解答時間は90分とする。前回は1問30分だったが、今回は量を増やす。問題の難易度も上げる。問題1が解けるまで、問題2を見ることはできない。起動時引数の個数異常や、フォーマット異常を考慮したロジックは不要とする。問題に書かれた仕様を充たすだけで良い。Perlが無理ならコメントで逃げる。Perlの構文やイディオムが分からないせいでどうしてもロジックが書けない場合は、コメントを使ってロジックを表現する。これはあくまで最終手段とする。#(以下略)*1最後の「コメントで逃げる」というルールについては、「そんなバカな」と思われる人がいるかもしれません。確かにかなり変なルールですが、解けなかった人がまた出てきた場合に、ロジック自体が頭の中でできていなかったのか、それとも使用する言語のせいで動作するプログラムが書けなかったのかを判断するための苦肉の策として用意しました。前回から変わらない点それ以外は基本的に第1回と同じルールになっています。ターミナル/コマンドプロンプト上で動作するプログラムを作成する。インターネットや書籍の利用を許可する。解答そのものを検索したり、メインロジックを全く不要にするようなライブラリの使用は禁止する。投票によって優勝者を決定する。メンバーの前で動作確認とプログラムの説明を行う。メンバーは気に入ったプログラムを3本選出し、投票する。評価ポイントは基本的に個人の自由。1位3点、2位2点、3位1点となり、合計点が多い人が優勝。コンテストの目的:自分のスキルを相対的に評価する。他人のロジックやコードから新しい発見を得る。良い意味でメンバー内の競争心をあおる。出題者は解答と投票には参加するが、評価の対象にはならない。(順位は付かない)当日の参加人数プログラマは自分を含めて11人。当日は家庭の事情により出席でないメンバーが2人いた。今回はFizzBuzz問題よりもずっと難しいです。簡単そうに見えますが、実際やってみると「あれれ??」となってしまう人が結構いるんじゃないかと思います。このブログを見てる方の中にはかなりの強者もたくさんおられると思うので、優秀な皆さんなら、さらっと解いてしまうと思いますが・・・。されたアルファベットを数字に変換する。変換ルールはExcelの列名と同等。入力された数字をアルファベットに変換する。問題1で作ったプログラムを拡張すること。AA問題1も問題2も、見た目はどちらも同じような難易度に見えますが、実は問題2には大きな落とし穴が潜んでいます。問題2は問題1よりもはるかに難しいです・・・!!で、実際にやってみた実はコンテストの前においらはこの問題を解いてました。使った言語はF#とC#です。Perlでは解いていません。最初60分にしようと思っていた解答時間を90分に伸ばしたのは、実際にやってみて予想以上に難しいことがわかったからです。そんなわけで実装すべきロジック自体はやる前から完全にわかっていました。楽勝楽勝〜♪とTest::Moreを使ってテスト駆動開発を始めたのですが・・・。ごめんなさい、Perlをナメてました。Perlは決して得意な言語ではありませんが、基本構文ぐらいなら大体理解しているつもりです。この問題で使いそうな標準関数も事前にチェックしていました。実際書いてみると変なエラーが続出したり、サブルーチンの引数の受け渡し方法が分からなくなったり、思ったようなスピードで解き進めることができませんでした。あと、その日は運悪くPCのウイルスチェックが走ってしまい、やたらPCが遅かったのも痛手でした。実行するのに毎回5秒以上待たされる始末。うわ、エラーが出た!修正!実行!・・(5秒)・・あれ?またエラーが出た!よし修正!実行!・・(5秒)・・ああっ、またエラーが!というテンポはかなり辛かったです。事前に考えていたペース配分では第1問30分、第2問45分、リファクタリング15分、ぐらいで考えていたのですが、なんと第1問だけで1時間も食ってしまいました。ロジックが最初からわかっているおいらですらこんな状況なので、他のメンバーは結構悲惨な感じでした。90分が経過したはい、それまで!!・・・と切り上げたかったのですが、おいらも含めて周りはまだ誰も完全に終わっていない様子・・・。マネージャーも「終わって・・・いいのかな?」みたいな感じで、すぐには終わりの合図を出せないようでした。結局おいらは90分と5分ぐらいで第2問まで完了しました。第1問を解けたメンバーが7人。解けなかったメンバーが3人。1人は90分以内には解けなかったものの、動作確認の時間までには何とか完成させたそうです。第2問を解けたメンバーは残念ながら一人もいませんでした。今回こそは全員に解答してもらって、楽しい動作確認とプログラム説明タイムにしようと思ったのですが・・・。難易度と解答時間の適切なさじ加減は本当に難しいです。コンテストが前編・後編の2部構成に本当であれば第2問の動作確認とプログラム説明をメインにしようと思っていたのですが、誰も解けていない以上、そんなことをしてもほとんど意味がありません。そこで急遽ルールを変更し、第2問は各自の宿題とすることにしました。適当に空いている時間を見つけて、じっくりと解いてもらうことにしました。動作確認&プログラム説明タイムも2日にわけます。この日の説明は第1問に限定し、第2問の説明タイムは1週間後の11月7日に実施することになりました。このエントリのタイトルに「前編」という文字が入っているのはそれが理由です。実はこのエントリを書いている現時点では、コンテストは完全に終わっていないのです。スピード重視の前編と、品質重視の後編にうまく分かれて、面白そうじゃない?と、自分に言い聞かせるようにしています。orz動作確認&説明タイムというわけで第1問に限定した動作確認&説明タイムが始まりました。FizzBuzz問題と違って、今回の問題はパッと見ただけではどういうカラクリで動作しているのか、なかなかわかりづらかったです。プログラムを書いた本人の中では筋が通っていても、第三者がそれを見ると一体何をやっているのか、すぐにはわからないものです。説明を聞いていると全員のロジックはそこまで大きく変わったのものではないことが徐々にわかってきました。ほとんどのパターンは、以下のようになります。"XFD"を変換する場合X、F、Dを後ろから一文字ずつ取得する。