うらおブログ(移転しました)スマートフォン用の表示で見るやねうらおブログ(移転しました)この広告は、90日以上更新していないブログに表示しています。2005-10-07やねう企画2005年入社問題解答と解説(2)program問2.問2.は、ペイントアルゴリズムを書けるかという問題である。seedfill」(→http://www2.starcat.ne.jp/~fussy/algo/algo3-1.htm)が有名だが、その根底には、この問題で見たように再帰→非再帰に変換したあと、値(seed)のpushを出来るだけ減らそうという発想のもとに考案されている。そこで、今回は再帰版と非再帰版とを書かせるという、ちょっと意地悪な出題の仕方をした。再帰版はたいていの人が書けていたが、非再帰は半数ぐらいの人しか書けていなかった。それも、私が求めている答えを書いてきている人は全体の2割以下という低い数字だった。書けなかった人は、解説を読みながら、自分に何が足りないのかを考えてみて欲しい。ところで「再帰」を「再起」とする誤字が目立った。日ごろ再帰を使っていないのだろう。0.ちょっと見慣れない(?)記法だが、説明のために私が時々用いる記法で、最後に評価した式が関数の値として返る言語だと思っていただきたい。C言語で書くならば、以下のようになる。(a[x][y]=1)+W(x-1,y)+W(x+1,y)+W(x,y-1)+W(x,y+1);などと書けなくもないが、ここまでする必要はないだろう。(!(a[x][y]++))とするのも無くはないのだが、if式が不成立のときは本来インクリメントは不要なので、少し無駄かなぁという気はする。a[x][y]=1の代わりにa[x][y]++と書いてきている人が何人か居たが、これだとread-modify-writeになるので、前者より遥かに劣るコードだと思う。min(6,y+1))のようなhackもある。(可読性の点からあまりお勧めはしないが)プログラムの仕組みについての解説は特にしなくとも良いと思うのだが、a[x][y]=1と迷路自体を塗りつぶしていくのがミソで、これが再帰を停止させるトリガーとなっている。ちなみに、迷路自体を潰すことが許されていないのならば、事前にコピーしておくか、その塗りつぶした領域をどこかに記憶しておく必要がある。(上記プログラム中のmapはC++で言うところのstd::mapだと思ってください)次に、非再帰版である。再帰とは、言うまでも関数が自分自身の関数を呼び出すことである。初心者にとって、そんなことをして、ローカル変数が破壊されたりしないのか、という疑問もあるだろうが、ローカル変数はスタック上に確保されているので、問題は無いのである。再帰から非再帰へは本来、仮想スタックを導入してローカル変数と関数呼び出し履歴をその仮想スタックを使って実現すれば良いだけだ。再帰型から非再帰型へは仮想スタックさえあれば自動的に変換できるものである。よって、非再帰版は再帰版から機械的に変換されたような(等価な)プログラムでなければおかしい。非再帰版を書くのに際して、まったく別のアルゴリズムを持ち出したのでは何をやっているのかわからない。電子書籍になるに至るまでの話ブログちょっとだけ移転のお知らせ時代はまだゲームセンターあらしに追いつかないのかやねうら王、電王戦バージョン提出しました将棋の神様のレーティングはいくつなのか?月別アーカイブはてなブログをはじめよう!yaneuraoさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。