2016年07月30日
ループの次元:その2
前回の「ループの次元:その1」では、コンピューター・プログラムにおける多重ループの多重度が「次元」を表している、という話をした。
この多重ループによって、自己相似イヤリングを描くことはできるのだろうか?
かなりややこしいことをする必要があるが、多重ループによって自己相似イヤリングを描くことは可能である。
ただここではプログラミングの技術そのものを語る場とは考えていないので、詳しく書かないことにする。
自己相似イヤリングを描くために「かなりややこしいこと」を駆使して無理矢理多重ループで複雑なプログラムを書こうとするよりももっと直感的に理解しやすいプログラミングのやり方がある。
再帰関数である。
この多重ループによって、自己相似イヤリングを描くことはできるのだろうか?
かなりややこしいことをする必要があるが、多重ループによって自己相似イヤリングを描くことは可能である。
ただここではプログラミングの技術そのものを語る場とは考えていないので、詳しく書かないことにする。
自己相似イヤリングを描くために「かなりややこしいこと」を駆使して無理矢理多重ループで複雑なプログラムを書こうとするよりももっと直感的に理解しやすいプログラミングのやり方がある。
再帰関数である。
自己相似イヤリングを描く再帰関数を、仮想プログラミング言語で書いてみると下記のようになる。
1: 関数:イヤリングを描く(カウント) [
2: 顔を描く
3: カウントをひとつ減らす
4: もしカウントが0でなければ [
5: 関数:イヤリングを描くを呼んで左耳のイヤリングを描く(カウント)
6: 関数:イヤリングを描くを呼んで右耳のイヤリングを描く(カウント)
7: ]もし条件ここまで
8: ] 関数ここまで
これをひとつひとつ追いながら見てみよう。
まず、この再帰関数をカウント=3で呼んでみる。
これを「レベル1」と呼ぼう。
2行目で顔が描かれる。
3行目でカウントが一つ減り、2となる。
4行目では"0でなければ"に合うので5行目に進む。
5行目でカウント2でこの関数が呼ばれる。
これを「レベル2」と呼ぼう。
レベル2の2行目で顔が描かれる。
3行目でカウントが一つ減り、1となる。
4行目では"0でなければ"に合うので5行目に進む。
5行目でカウント1でこの関数が呼ばれる。
これを「レベル3」と呼ぼう。
レベル3の2行目で顔が描かれる。

3行目でカウントが一つ減り、0となる。
4行目では"0でなければ"に合わないので8行目まで進み、この関数から抜ける。
関数から抜けたら、この関数の呼び元のレベル2の5行目に戻り、6行目に進む。
今度は右耳を描くためにカウント1でこの関数が呼ばれる。
また「レベル3」になる。
レベル3の2行目で顔が描かれる。
3行目でカウントが一つ減り、0となる。
4行目では"0でなければ"に合わないので8行目まで進み、この関数から抜ける。
関数から抜けたら、この関数の呼び元のレベル2の6行目に戻り、7、8行目に進み、この関数から抜ける。
関数から抜けたら、この関数の呼び元のレベル1の5行目に戻り、6行目に進む。
今度は右耳を描くためにカウント2でこの関数が呼ばれる。
また「レベル2」になる。
。。。
と繰り返していくことで、自己相似イヤリングが描かれる。
この操作をもう一段深く、最初にカウント=4でこの再帰関数を呼ぶと、最終形は下記のようになる。
以上のように、再帰関数での再帰的な呼び出しを順を追いながら見てみたが、ここで肝心なことは、プログラム中のどこにも、「ループ」という言葉が使われていない、ということである。
再帰関数は確かにループをするものであるが、そのループが再帰的であるため、一般的なループでは表せない入れ子構造を表すことができる。
これは、「多重ループは多次元を表している」という前回の話における「次元」とはまた違った意味での「次元」とでも言うべきものである。
1: 関数:イヤリングを描く(カウント) [
2: 顔を描く
3: カウントをひとつ減らす
4: もしカウントが0でなければ [
5: 関数:イヤリングを描くを呼んで左耳のイヤリングを描く(カウント)
6: 関数:イヤリングを描くを呼んで右耳のイヤリングを描く(カウント)
7: ]もし条件ここまで
8: ] 関数ここまで
これをひとつひとつ追いながら見てみよう。
まず、この再帰関数をカウント=3で呼んでみる。
これを「レベル1」と呼ぼう。
2行目で顔が描かれる。

4行目では"0でなければ"に合うので5行目に進む。
5行目でカウント2でこの関数が呼ばれる。
これを「レベル2」と呼ぼう。
レベル2の2行目で顔が描かれる。

4行目では"0でなければ"に合うので5行目に進む。
5行目でカウント1でこの関数が呼ばれる。
これを「レベル3」と呼ぼう。
レベル3の2行目で顔が描かれる。

4行目では"0でなければ"に合わないので8行目まで進み、この関数から抜ける。
関数から抜けたら、この関数の呼び元のレベル2の5行目に戻り、6行目に進む。
今度は右耳を描くためにカウント1でこの関数が呼ばれる。
また「レベル3」になる。
レベル3の2行目で顔が描かれる。

4行目では"0でなければ"に合わないので8行目まで進み、この関数から抜ける。
関数から抜けたら、この関数の呼び元のレベル2の6行目に戻り、7、8行目に進み、この関数から抜ける。
関数から抜けたら、この関数の呼び元のレベル1の5行目に戻り、6行目に進む。
今度は右耳を描くためにカウント2でこの関数が呼ばれる。
また「レベル2」になる。
。。。
と繰り返していくことで、自己相似イヤリングが描かれる。
この操作をもう一段深く、最初にカウント=4でこの再帰関数を呼ぶと、最終形は下記のようになる。

再帰関数は確かにループをするものであるが、そのループが再帰的であるため、一般的なループでは表せない入れ子構造を表すことができる。
これは、「多重ループは多次元を表している」という前回の話における「次元」とはまた違った意味での「次元」とでも言うべきものである。