Hatena::ブログ(Diary)

Qu記(仮) RSSフィード

2011年 03月 17日

Herbert Tutorial 2 - 引数なしプロシージャ / 同じ処理を一つにまとめる

前回はHerbertを動かす基礎である、s,r,lの3つの基本要素を勉強しました。

これで、原理的にはHerbertにあらゆる動きをさせることが可能になったわけですが、だからといって、これでHerbertの全てが分かったということになるかと言えば、当然そんなのはウソです。

だって、一歩一歩動かさせるなんて、面白くもなんともありませんね。

何度も繰り返しているように、Herbertの醍醐味は「規則の発見」と「動的な記述」、それらの実現である「ショートコーディング」にあります。

そして、こうやって「何度も繰り返し述べる」ことはムダです。

では今回はこの、「ムダを省く」ということをテーマに学んでいきましょう。

以下、前回の演習問題の解答を題材に、ショートコーディングの第一歩である「引数なしプロシージャ」の書き方を勉強します。


練習問題1の解法

さて、皆さん前回の練習問題にはもう取り組んでもらえましたか?

まだの人はhttp://herbert.tealang.info/problem.php?id=144にアクセスして解いてみましょう。

以下、この問題の想定解法です。

f:id:quolc:20110318001417p:image

(コード)


ssrssrrssssrssrsslss

多分、詳しい説明は不要ですね。

前進 -> 前進 -> 右折 -> 前進 -> 振り返り(=右折+右折) -> ...

と律儀に一つ一つターゲットを踏んでいくだけです。

ここまでで追いつけてない人は、前回の内容をもう一度読み直しましょう。


15bytes!?

さて、ここまでコードのbyte数というものについて詳しく解説していませんでした。

これはゲーム画面の上の部分に表示されている数字で、コードをあれこれ書き換えるとそれにしたがって値が動いているのが分かります。

byte数というのは、簡単に言うと書いたコードの長さの事(これから出てくるカッコや演算子、カンマといったものは含みません)で、これが短いほどにシンプルなプログラムであると言えるわけです。

さて、それでは上に示した解答コードを見てみると、20bytesと表示されています。

この問題をクリアできる制限ギリギリのbyte数というわけです。

ここで、問題ページ下部のランキングを見てみましょう。

15, 15, ... 16, 16, 17... 何やら、20bytesよりも大分少ない値が並んでいます。

これはどういうことでしょうか。

上位プレイヤーはもっと良い経路を見つけて、たった15回のs/r/lでもって全部のターゲットを踏んだというのでしょうか!?

…そうして頭を抱えて効率的なルートを探すのも大切ですが、今回は事情が違います。

それでは、20bytesを縮めるテクニックを紹介しましょう。


「くどさ」を見つけよう

今一度、先ほどの解答コードをじっくり読んでみましょう。


ssrssrrssssrssrsslss

「なんかくどいな」と思う部分はありませんか?

「くどい」というのはつまり、何度も同じ部分が登場していないか、ということです。

コード短縮のポイントは、この「同じ部分コードの繰り返し」を見つけるところにあります。


実際に上のコードについて、例えば ssr という並びに注目してみると

ssr ssr rrss ssr ssr sslss

と、四回も同じ並びが登場していることが分かります。これはくどいですね。


あるいは、rssという並びに注目してみても

ss rss r rss ss rss rss lss

と、四回同じ並びが登場していることが分かりますね。


こういうくどさを一つにまとめてしまえるのが、「プロシージャ」です。


引数なしプロシージャ

プロシージャの概念はプログラミングを経験したことの無い人には少し複雑で難しいかもしれませんが、今回扱う引数なしプロシージャについては、単純に「長いコードをひとまとめにして何度も使えるようにしたもの」と考えてもらえればいいです。

プログラミング経験のある人は「関数」と同じものと考えてください。

引数なしプロシージャは次のように使います。


a:ssr
aaaa

上のコードを実際にテストフィールドで動かしてみましょう。

このコードは各辺2歩の大きさの正方形を描くものですが、普通に書くと


ssrssrssrssr

となるところを、一行目のa:ssrssrという4回も登場するパターンにaという名前に付けて、2行目でaを4回呼び出しています。

これによって、普通に書くと12bytes掛かったところを、8bytesに短縮することが出来ました。


このように、引数なしプロシージャは

(プロシージャ名):(プロシージャの内容)

という書式で定義することができ、以降はそのプロシージャ名をs,r,lのように使うことで、同じ処理を何回も効率的に書くことが出来るようになります。

なお、プロシージャの名前に使えるのはs,r,lを除いた小文字アルファベットのみなので注意。


ちなみに、プロシージャの中でプロシージャを呼び出すこともできます。


a:sss
b:aar
c:ab
cccc

のような感じで、s,r,lのようにaやbを書けばオッケーです。


練習問題1': 15bytesでTutorial 1を解く

それでは、引数なしプロシージャを上手く使うことで、前回の演習問題を短縮してみましょう!

上に紹介した手法で簡単に16bytesまで、頑張れば15bytesまで短縮できます。

15bytesの解答を見つけられたら、もう引数なしプロシージャの使い方はマスターしたと言ってよいでしょう!


練習問題2

それでは最後に、今回のまとめになる練習問題です。

ちょっと難しいかもしれませんが、頑張って解いてみましょう!

http://herbert.tealang.info/problem.php?id=199


次回は、命令引数プロシージャという記法を勉強して、今回注目した「くどさ」を一般化することで、さらなるコードの短縮を目指します。

また、次回からはプログラミングらしさが強くなってくるので、お楽しみに!

それでは、さようなら。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証