あ、すっかり最後になってしまいましたが、この記事は釧路AdventCalendar2013 12/09の記事となります。
ここまで長々と読んで下さいまして、誠にありがとうございます。
それでは皆様良い年末を!
初めましての方、初めまして!
お久しぶりの方、いませんね、初投稿です!
江戸っ子、生っ粋
を名乗っている生粋の釧路っ子、東京社会人のすがや@misty320 と申します!
言いたいことは既に終わってしまったのですが…万が一細部が伝わっていなかったら残念だなぁと思い
恥ずかしながら結論に至るまでの経緯をご説明させて頂こうと決意いたしました。
恐縮ではございますが今暫くのお付き合いをお願い致します。
これをお読みいただいている皆さんもいざ「釧路について書け」と言われたら、
何を書くのが正解なのか迷うのではないでしょうか。
ということで、僕はまず *釧路とはいったい何なのか* に向き合うことにしました。
釧路…くしろ…946…そう、釧路と言えば946ですね。
皆様ご存知の通りAdventarの釧路のページトップにすら
>946って駅にネオンありますね〜!ちょっと恥ずかしいですねー。
と書かれる始末。
駅や市内各所に掲げられる946と*9464649(くしろよろしく)*のフレーズ...アベニュー946...
これはもう釧路=946と言っても過言ではない。否、言わなければ不足があるくらいでしょう。
反射的にwikipediaで946を調べましたとも。ええ。結果はこちら。
語呂合わせで釧路を指す。
やっぱりな! さて、そのほかは…
946 は合成数であり、約数は 1 , 2 , 11 , 22 , 43 , 86 , 473 と 946 である。
22番目の六角数であり、一つ前は861、次は1035。
43番目の三角数でもある。一つ前は903、次は990。
なるほど、どうやら釧路は 「合成数」 かつ 「六角数」 かつ 「三角数」 であるということらしいです。
ここまでで皆様にも釧路とはいったい何なのか良くご理解いただけたかと思います。
そして当然、ここで一つの疑問にぶち当たったことと拝察いたします。
そう、 946に甘んじていて良いのか? と。
※申し遅れましたが、僕は釧路高専情報工学科を卒業してエンジニア(プログラマ)をやっております。
釧路出身の人間として、エンジニアとして、釧路の未来を見つけ出さねばなりません。
さぁ、一緒に釧路の未来、946を超える釧路の数を見つけましょう!コンピュータの力によって!
- 以下でプログラムの話が出てきます。
興味の無い方は枠で囲まれた部分は読み飛ばして頂いて問題ございません。
ただ可能な限りシンプルに、初心者向けに書いたつもりですので、ご一読くださると嬉しいです。
もしこれを機に「プログラミングしてみたいよ!」っていう奇特な方がいたら、
可能な限りの補足説明もいたしますので、すがや@misty320までお気軽にご連絡ください。
- 946より大きな合成数かつ六角数かつ三角数を見つける
という問題を数学的に解く事も出来るのだろうとは思います。
しかし僕は数学はさほど得意ではないので考えたくありません。
そこで僕よりも計算が得意なコンピュータ様の力を借りて、
テスト駆動開発(Test-Driven-Development;TDD)という手法を用いて釧路の未来を見つけたいと思います。
プログラミングおよび開発手法にあまり興味の無い方にはなじみの無い言葉かと思いますので簡単に説明すると
- 最小単位のゴール条件を先に作成する。
- それをクリアできるようなものを作る。
という手順を繰り返す開発手法です。
現実でたとえると、「授業の始めに毎回小テストをする先生」のようなものでしょうか。
それでは開発を始めましょう。※厳密なTDDをやるとすごく長くなってしまうので、多少省略しながら進めます。
「釧路のうんたん」という遠くの目標はいったん忘れて、
- 「合成数を調べられるか?」
の小テストを作ります。
さらに厳密にいうと合成数は「1と素数で無い数」なので、もっと小さな
- 「素数を調べられるか?」
の小テストを作ります。
なお、本件では整数のみが与えられるものと仮定します。
public function test_与えられた数字が素数か分かる() { //余談だけど今時のプログラムはある程度日本語で書けますよ。 $obj = new Kushiro(); $result = $obj->isPrime(1); $this->assertFalse($result, '1は素数ではないのでfalse'); $result = $obj->isPrime(2); $this->assertTrue($result, '2は素数なのでtrue'); }
こんなところでしょうか。
当然、この時点ではプログラム本体が無いのでテストはクリアできません。
PHP Fatal error: Call to undefined method Kushiro::isPrime()
と、怒られてしまいました。準備をしないでテストに臨んで怒られる、よくある話です。
なので、まず最低限、内容はどうでもいいのでそれっぽいプログラムを書きます。
class Kushiro { public function isPrime($num) { return true; } }
Tests: 1, Assertions: 2, Failures: 1.
怒られなくなりましたが、中身が無いのでテストをクリアすることはできませんでした。
では、素数を判定するプログラムを書いて見ます。
public function isPrime($num) { //2未満は素数ではない if($num < 2) return false; //2以上、その数自身未満まで試す for($i=2; $i < num; $i++) { //割り切れた場合は素数でない if($num % $i == 0) return false; } return true; }
テストを試します。
OK (1 test, 2 assertions)
ほめられた!やったね!
でもまだちょっと不安だったので4,5,997,999もテスト内容に追加して再度実行しましたが、やはりOKでした。
TDDの開祖、ケントベック先生も「不安はテストコードに表せ」と言っていたので、不安な場合はテストを追加すると良いです。
さて、それでは一歩進めて合成数の判定プログラムを作ります。
テストはこう。※見やすくするため一部省略してます。
public function test_与えられた数字が合成数か分かる() { $obj = new Kushiro(); $result = $obj->isComposite(1); $this->assertFalse($result, '1は合成数ではない'); $result = $obj->isComposite(997); $this->assertFalse($result, '997は合成数ではない'); $result = $obj->isComposite(999); $this->assertTrue($result, '999は合成数'); }
テスト対策をします。
public function isComposite($num) { //2未満は合成数ではない if($num < 2) return false; //素数か?の逆 return !$this->isPrime($num); }
いざテスト。
OK (2 tests, 11 assertions)
やったね!
同じ要領で三角数、六角数についてもプログラムを作成し、
それらを組み合わせて作った「この数字は釧路か?」がこんな感じです。
完成したプログラムに946から先の数字を流し込んであげることにします。
946 は釧路です 947 948 ... 1034 1035 は釧路です 1036 ... 1127 1128 は釧路です 1129 ... 1224 1225 は釧路です 1226 ...
キタ―――(゚∀゚)―――― !!
946と同じ性質を持ち、946を上回るスゴイ奴ら!それはずばり1035,1128,1225です!
まだまだ探せば出てくるのでしょうが、とりあえず最初の一歩としてはこの辺りを目指すのが妥当ではないでしょうか!
ついに冒頭にて提示した結論に至ることができました。
そう。テスト駆動開発はすばらしいものであると。
テスト駆動開発は単にテストの順番が前後したり、テストの作り忘れがなくなるというものではありません。
- 問題の性質を詳細に分析しなければならなくなるので、問題の本質が見えやすくなる。
- 細かい単位で成果物の正しさを確かめられるので、頻繁に「進歩している感」が得られる。
という副産物を生み出します。
そしてこれらの副産物は、プログラミングに限らずさまざまな場所で有効なものだと僕は考えています。
難問に挑むのではなく、簡単な問題から解き進めていくことで自信をつけながら勉強をする。
ひとつの問題の中でも、簡単にできそうな部分から細かく確かめながら進めていく。
会議や仕事の「遠くの最終目標」を「小さな複数の目標」に噛み砕くことで見通しをあげる。
こういう考え方は、実務上とても有効な場合が多いと感じています。
ぜひ皆さんもいろいろな場面にTDDを取り入れてみてはいかがでしょうか!
長々とお付き合いくださり本当にありがとうございました!
プログラミング、すがやに興味のある方は気軽に話しかけてくださいね☆(ゝω・)vキャピ
さて、明日の担当はAkira Ouchiさんです!
本名だと良く分からなかったのですが(多分)Ejectコマンドユーザー会のあの方ですね!
僕個人としては夏コミでちらりとお会いしたことがある気がするのですが覚えておいででしょうか(笑)
今回はいったいどんなEject技が見られるのかッ!乞うご期待!
あわせて読みたいTDD情報。
http://mint.hateblo.jp/entry/2013/12/09/102613
同日にTDDネタかぶせてくる素敵な同僚です。