カテゴリー
読み物

終わりから考える

今、あなたの前にはグラスが2つ。片方にはジュースが、もう片方には水が入っている。どちらも同じ量が注がれているようだ。

ここで、スプーンを取り出して、まずジュースのグラスからひとさじ分をすくい、水のグラスに入れてかき回す。水は少しだけジュースを含み、少しだけ不透明になって、ひとさじ分だけ多くなる。今度は逆に、水のグラスからスプーンひとさじをすくい取り、ジュースのグラスに入れてかき回す。水のグラスからは、ほとんどひとさじ分の水と、ほんの少しのジュースが取り出されてジュースのグラスに入ったはずだ。ジュースのグラスの中身は、少しだけ薄くなり、二つのグラスの液体の量は元に戻って等しくなる。

さて、このスプーンでの液体の移動をあと二往復させ、全体で三往復させてみる。水のグラスはジュースを含んで少し不透明になり、ジュースのグラスは水を含んで少し薄くなる。ここでクイズ。ジュースのグラスから水のグラスに移動したジュースの量と、水のグラスからジュースのグラスに移動した水の量は、どちらが多いだろうか?

我々は賢いので、式を立てて手順を追うことができる。最初にコップに入っていた液体の量を\(L\) 、スプーンひとすくいの量を\(s\)とすると、最初のひとすくいの移動で左(ジュースのグラス)から右(水のグラス)へは\(s\)だけのジュースが移動し、右のグラスのジュースの濃度は\(s \over {L + s}\)になった。その次の移動では右から左へ\(s {s \over {L + s}}\)だけのジュースが移動し、左のグラスのジュースの量は\(L-s + s {s \over {L + s}}\)になる。これをあと2往復繰り返していけば、最終的なジュースや水の量が求まる…。

という風にいきなり式を立ててしまうことはないだろうか。もちろん、その方針で計算していくことは可能だ。面倒だと思うけれど。

ここで、いったん途中の操作を忘れて、最後の2つのグラスの様子を想像してみよう。少し薄くなった左のグラスと、少しだけ色がついた右のグラス。それぞれはジュースと水が混ざった状態なのだけれど、グラスの中でジュースと水を分離してしまうことを想像したらどうなるだろうか。どんな絵が描けるだろうか。左のグラスはほとんどジュースで少しだけ水、右のグラスはほとんど水で少しだけジュース。ジュースと水はこの2つのグラスの間を移動しただけなので、増えも減りもしない。ということは、移動したジュースの量と、移動した水の量は同じになるに決まっている。最初の問題に戻ると、「ジュースのグラスから水のグラスに移動したジュースの量と、水のグラスからジュースのグラスに移動した水の量」を聞かれているのだから、これは「等しい」が答えになる。

わかってしまえば当たり前のことなのだけれど、手順を追って考えていこうとすると、妙に面倒になり、考え間違いが起きそうな問題だった。しかし、「操作の結果、どうなったのか?」を考えるようにすると、途端に考えるのが簡単になる。実はプログラミングでも同様の場合がある。プログラムの書き方を初めて学ぶとき、手順を追って、何が起きるかを追いかけるような学び方をすることが多いだろう。このような「順方向」の追いかけ方は、多くの学生さんが身に着けられているように感じる。しかし、プログラムを与えられたとき、「このコードが動くと、結局どうなるの?」と聞くような「逆方向」の考え方になると、途端に苦手意識を持つ学生さんが多いようだ。

典型例が、再帰という考え方を学ぶときだろう。再帰のコードを見て、手続きの動きを追っていってだんだん意味が分からなくなってしまう人は、いったん考え方を逆方向にして、「結局どうなるはずなのか」から考えてみる必要があるかもしれない。この関数が終わると、結局この配列がどんな状況になっているのか。手続きの流れを追わずに、関数の「目的」を考えてみることはできるだろうか。プログラムを書く時には、実は「順方向」と「逆方向」を自由に行き来できる能力が必要になる。時には、意識して思考する訓練が必要になるだろう。宣言的なプログラミング言語に触れてみるのも良いかもしれない。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です