Check our Terms and Privacy Policy.

低学年児童のためのプログラム教育教材の作成とそのための実践:第一版 (2nd)

プログラミングという概念は、手続きを書くことと同義ではありません。 プログラムそのものの概念の把握から、プログラミングの考え方の多様性を理解できる教材を目指します。 主に小道具を使うアンプラグドな環境においてパズルやゲームを題材としたものを想定しています。

現在の支援総額

4,000

0%

目標金額は2,080,000円

支援者数

1

募集終了まで残り

終了

このプロジェクトは、2017/08/02に募集を開始し、 2017/08/30に募集を終了しました

このプロジェクトを見た人はこちらもチェックしています

低学年児童のためのプログラム教育教材の作成とそのための実践:第一版 (2nd)

現在の支援総額

4,000

0%達成

終了

目標金額2,080,000

支援者数1

このプロジェクトは、2017/08/02に募集を開始し、 2017/08/30に募集を終了しました

プログラミングという概念は、手続きを書くことと同義ではありません。 プログラムそのものの概念の把握から、プログラミングの考え方の多様性を理解できる教材を目指します。 主に小道具を使うアンプラグドな環境においてパズルやゲームを題材としたものを想定しています。

このプロジェクトを見た人はこちらもチェックしています

「普通のバブルソートと普通ではないバブルソート」に挙げた “pat” は3次元の配列でした。ここで、すこし見てみましょう:pat = [ [[2, 1], [1, 2]], [[3, 1], [1, 3]], [[4, 1], [1, 4]], [[5, 1], [1, 5]], [[6, 1], [1, 6]], [[7, 1], [1, 7]], [[8, 1], [1, 8]], [[9, 1], [1, 9]], [[3, 2], [2, 3]], [[4, 2], [2, 4]], [[5, 2], [2, 5]], [[6, 2], [2, 6]], [[7, 2], [2, 7]], [[8, 2], [2, 8]], [[9, 2], [2, 9]],  [略] [[7, 6], [6, 7]], [[8, 6], [6, 8]], [[9, 6], [6, 9]], [[8, 7], [7, 8]], [[9, 7], [7, 9]], [[9, 8], [8, 9]]] これだとわかりにくいかもしれませんが、この “pat”が3次元の配列だということは、「普通のバブルソートと普通ではないバブルソート」に挙げた後者のプログラムのこんなところで確認できます:    if data2 == pat[k][0]:     # C     data1[i] = pat[k][1][0]     data1[i+1] = pat[k][1][1]     print("FIND", data2, "->", pat[k][1]) ここで、“data1[i] = pat[k][1][0]” として、たとえば “[[2, 1], [1, 2]]” という要素の、 “[1, 2]” の、 “1” などにアクセスしています。添字が “[k]”、 “[1]”、 “[0]” と3つあり、それで表記上の最深部の要素にアクセスできていますから、3次元であることは問題なく理解できるかと思います。 さて、この “pat” ですが、配列であるとともに、リストでもあります (すくなくともPythonの用語としては)。実際、 "pat.append([[10, 9], [9, 10]])” とすると、上に示したものの最後に “[[10, 9], [9, 10]]” が追加されます。このように、大きさが可変なのはリストの特徴でもありました。 ところで、配列というと、その要素へのアクセス方法、あるいは表記の方法としては、 “pat[k, 1, 0]” という形も一般的です。なぜ、この “pat” では “pat[k][1][0]” という表記になっているのでしょうか。 答えの一つは簡単で、 “pat” の “k番目の要素” の、 “1番目の要素” の、 “0番目の要素” にアクセスするという書き方だからです。あるいは別の答としては、“pat” というオブジェクト (ここではリスト) の “k番目のオブジェクト (ここではリスト)” の、 “1番目のオブジェクト (ここではリスト)” の、 “0番目のオブジェクト (ここでは整数)” にアクセスするという書き方とも言えます。 Pythonのソースコードをきっちり見たことはありませんが、Rubyは、ネット・ニュースにソース・コードが流されていた時代に、ちょっと覗いたことがあります。Rubyの場合、上の例に出てくる “[” や “]” もメソッドとして定義されています。そこで、 “[” あたりの定義をRuby自身で書き換えてやることで、私は連想配列を実装していました。これは、当時、私はjgawkに慣れ親しんでおり、「連想配列、便利だなぁ」と思っていたことからやったことです (多次元配列はどう書くんだろうと思ったからという理由もあったことは内緒です)。ですが、これができるということは、Rubyはオブジェクト指向であることを徹底していることの証左とも言えるでしょう。 さて、この “pat” は、同時に木構造でもあります: 普通の配列、つまりはメモリ領域をいっぺんに確保するような配列では、その個々の要素の間にはこのような入れ子の関係はありません。このような図示が可能なのは、リストの入れ子の形で配列を実現しているからです。(もちろん、普通の配列でも、入れ子であると意識して(思い込んで)扱うことは可能です。) リストの入れ子は、自然と木構造にもなります。では、木構造はリストの入れ子の形でしか現わせないのでしょうか。もちろん、そんなことはなく、普通の配列でも現わせます。ですが、その紹介は後の機会にとさせていただきます。


まず最初にですが、プロジェクトの本文や、活動報告についての感想、ご意見、ご質問を、ぜひコメントでお寄せいただければと思います。現在は支援募集期間中であり、本企画の実施期間ではないため、お寄せいただいた感想などについてはリターンとしてではなく、お返事や回答をさせていただきます。 では、本題に入ります。 本企画で作る教材に、どのようなパズルやゲームを採用するかですが、それは本企画の実施期間中の講習で選びたいと思います。 「パズルやゲームの題材はどうするんだ?」という疑問もあるかもしれません。ですが、本文に書いた『コンピュータ使わない情報教育 アンプラグドコンピュータサイエンス』であるとか、『別冊サイエンス コンピューターレクリエーションI 遊びの発想』や『別冊サイエンス コンピューターレクリエーションII 遊びの探索』、あるいはそもそも情報工学関係の教科書や専門書にも普通にパズルやゲームが例題や課題として現われます。ですので、どういうパズルやゲームを作るかという点では困ってはおらず、むしろどれを選ぶかが課題であり、講習をとおして採用するものを選びたいと考えています。 一つ問題があるとすれば、それらのパズルやゲームのすくなくない割合が「探索」を含むということです。探索が入ると、教材の課題として使うにはちょっと難しいかもしれませんし、あるいは複数の課題で探索を使う必要があるのかという疑問もあります。 それはそれとしてですが。 この話題を教材に入れたいとは思うけれど、入れる必要があるのかと悩んでいるものがあります。それは、「ガジェット・コンピューティング」と呼ばれたりするものです。おおまかにはアナログ・コンピューティングの一種なのですが、たとえばスパゲッティ・ソートとか、そのほかのものとか。 こういうものの紹介だけでも教材に入れたいと思っている理由は単純なものです。つまるところ、多くの人がこうだと思っているだろう「計算という概念」に疑問符を示したいからです。たとえば、『別冊サイエンス コンピューター・ソフトウェア』の「9. 科学と数学のソフトウェア」にてS. ウォルフラムが述べているように:| 物理的システムは計算システムと考えられており,| コンピューターが行なうのと同様のやり方で情報を| 処理していると考えられている。 ということを、そもそもの理解の根幹、あるいはその一つとして示したいという考えもあります。(「物理的システム」というのは、そこらへんにいくらでもあるものを指しています。そこには、生物が行なっている化学反応や、地球の環境、太陽系などなども含みます。) ですが、そのような概念にどれだけの人が賛成するか、さらにはそのような概念をどれだけの人が理解できるかという点において、この話題を教材に入れた方がいいのかどうかを悩んでいます。もっとも、面白いから入れればいいじゃないかとも思っています。講習で試してみて、その反応で決めるのがいいだろうというのが現状です。


「普通のバブルソートと普通ではないバブルソート」で使った、 “[5, 9, 2, 1, 3, 7, 6, 4, 8]” という配列でちょっと話をしてみます。 ソートのアルゴリズムはいくつもあるのですが、講習をやった際におそらく出てくるだろうアルゴリズムの一つにバブルソートがあるかと思います。もう一つおそらく出てくるだろうアルゴリズムとして、選択ソートがあると思います。選択ソートはwikipediaで読んでもらうとします。 ここでは、すこし変形した選択ソートを考えてみます。どう変形するかというと:1. 配列1に元データが入っている2. 空、あるいは特定の値で埋められた配列2を用意する3. 配列1の中から一番小さい値を、配列2の1番目 or i番目の要素として入れる4. 配列1のその要素を、無効ないし選択済みをしめす値に書き換える5. 3. と4. を適当に繰り返す こうすると、“[5, 9, 2, 1, 3, 7, 6, 4, 8]” はこのようになります (面倒なので “,” は書かないことにします):配列1       配列2 [5 9 2 1 3 7 6 4 8] → [][5 9 2 X 3 7 6 4 8] → [1][5 9 X X 3 7 6 4 8] → [1 2][5 9 X X X 7 6 4 8] → [1 2 3][5 9 X X X 7 6 X 8] → [1 2 3 4][X 9 X X X 7 6 X 8] → [1 2 3 4 5][X 9 X X X 7 X X 8] → [1 2 3 4 5 6][X 9 X X X X X X 8] → [1 2 3 4 5 6 7][X 9 X X X X X X X] → [1 2 3 4 5 6 7 8][X X X X X X X X X] → [1 2 3 4 5 6 7 8 9] このように、配列2にはソートされた結果が入ります。 さて、ではソートを課題とした場合、講習に参加した児童・生徒が、たとえばバブルソートを使った場合のみ正解とするべきでしょうか。あるいは逆の場合もあるでしょう。あるいは、もしかしたらマージソートを思いつく/知っている児童・生徒もいるかもしれません。そのような場合も誤りとするべきでしょうか。 このような場合、どれか一つのアルゴリズムのみを正解とするのはナンセンスでしょう。ですから、要求した結果が得られるなら、どのアルゴリズムを使ってもかまわないとします。同時に、どのようなデータ構造を使ってもかまわないとします。 「結果がちゃんと得られればいい」という態度とも言えるかと思います。この態度はあまりに適当と思われるかもしれません。 ですが、講習に参加した他の児童・生徒のやりかたと比べるという過程も講習に入れたなら−−もちろん入れますが−−、他のデータ構造とアルゴリズムが存在するのだということを確認できるということにも繋がるでしょう。ですので、むしろ積極的に、この適当な方法を選択したいと考えています。 むろん、ソートならソートとして、きちんと動くことを児童・生徒自身が理解することも必要ですし、他の児童・生徒に説明できることも必要です。この部分については「なんとなく」は認めません。「なんとなくを認めない」ためには、特定の具体的なプログラミング言語を用い、書いたプログラムをPCやタブレットで実行し、確認するという方法もあるかと思います。ですが、経験がある人にはわかると思いますが、「動いたことで確認とする」というのは、実は極めて甘い基準です。また、本企画の場合、「今回はこの言語かこの言語でやってみよう」などと、私が言い出しかねません(笑。 問題は、「なぜきちんと動くと言えるのか」を説明できること、あるいは強く言うなら証明できることです。その際、データ構造の図示は必須でしょう。また、同時に自然言語を使ってこの部分を行なうことも可能です。より形式的にするために、複数のパラダイムに対応した、処理系が存在する言語の使用や擬似言語を用意する方向も検討する必要があるかとも思います。もっとも、本企画の場合、いろいろな言語の型の要素を含んでいなければならないので−−ここで特定のパラダイムを採用すると、本企画の主張と矛盾しますから−−、擬似言語の設計も難しいのですが。それは置いておくとして、実行する環境が存在しないという点をむしろ利点として活用するという方向もあるのではないかと思います。もっとも、まったく動かないというのもつまらないので、擬似言語を用意するとしても、いずれなんらかの形で実装するかもしれないという可能性は残しておきたいと思います。    


本企画で目指す教材では、アルゴリズムよりもデータ構造に重きを置くと本文で書きました。ですが、データ構造とだけ言ってもわかりにくいかもしれません。そこで、基本的なデータ構造を紹介したいと思います。 まず、一つの値だけを保持するものがあります。これを次のように図示します: これ以降は、形や詳細はともかく、この「一つの値だけを保持するもの」のいろいろな組合せになります。 それらの最初のものとして、配列を見てみましょう: これは、横方向と縦方向に並んだ2次元の配列です。横方向だけ、縦方向だけに並んだ1次元の配列もありますし、3次元以上の配列もあります。先の「普通のバブルソートと普通ではないバブルソート」の後者における “pat” は、3次元配列の例です。また、上の図のように直接的な形での配列に限らず、配列の配列、配列の配列の配列などとして2次元以上の配列を実現する方法もあります。なお、情報にかかわる人は「多次元空間」という言い方を普通にしますが、それはただの配列、とくに4次元以上の配列を指しているだけだったりします。 配列は、 “matrix[1][2]” のように、数値の添字で要素を指定します。それに対して、名前で指定するもの、あるいは変数をまとめたものに、レコードがあります。図示すると次のようになるでしょう:   なお、オブジェクト指向の考え方にはいくつかあるのですが、その一つとしてレコードを拡張したものというものもあります。この場合、オブジェクトは次のように書けるでしょう:   配列やレコードには、すこし特殊なものがあります。配列は “matrix[1][2]” のように数字の添字で要素を指定します。レコードの場合は、 “record.first” のように、レコードの名前と、レコードを構成する変数の名前で要素を指定します。もし、“a["first"]” と書くような、これらが合さったようなデータ構造があったとしたらどうでしょうか。そして、もちろんそういうデータ構造は存在し、連想配列、あるいはハッシュと呼ばれます。これを図示すると、こうなるかもしれません:   次に、すこし複雑になりますが、よく使われるものとして木構造というものがあります: この図では左右のバランスが取れていますが、バランスは取れていなくてもかまいません。 木構造は、要素の親子の関係がはっきりしていますが、その部分をもっと柔軟にすると、グラフというデータ構造になります: グラフにおける要素間の繋がりには、方向があるものと、方向がないものがあります。 また、要素間の繋がりが輪の形になると、リングになります: リングは、リング・バッファなど、グルグル回りながらデータを書き換えていったり、データを読み出したりするようなものにも使われています。 リングのどこかを切って、切り口の片方をデータの入口とし、もう片方をデータの出口とすると、キューになります: これは、「最初に入ったデータが、最初に出る」ということで、“First In, First Out”、略して “FIFO” と呼ばれたりもします。 それに対して「最初に入ったデータが、最後に出る」というデータ構造もあり、スタックと呼ばれています。 “FIFO” に対応するような呼び方としては、“First In, Last Out”、 略して“FILO” などと呼ばれもします:   最後になりましたが、重要なデータ構造としてリストがあります。図示すると次のようになります: lisp系の言語では、細かい話を除けば、データ構造としてはこのリストしか存在しません。しかし、このリストで、これまで述べたデータ構造の全てを、配列も含めて実現できます。もちろん、配列でも同様に、これまで述べたデータ構造の全てを実現できます。ですが、基本的には、配列はその大きさが固定されています。対してリストは、大きさが可変だという特徴があります。 これらはあくまで基本的なデータ構造、あるいはその概略です。これらをどう用いるかにはかなりの自由度があったり、あるいは目的に対して向き不向きがあったりもします。これらのデータ構造に親しむことで、どのようなデータ構造とアルゴリズムの組合せでプログラムを書くと問題を解き易いのかがわかりやすくなったりもします。言い換えれば、アルゴリズムのみを考えることでプログラミングを行なうことはできないとも言えます。 本企画においてデータ構造を重視するのには、そのような理由があります。アルゴリズム一辺倒でのプログラミング教育は、はっきり言えば誤った方向を向いていると言えるでしょう。  


バブルソートというのは、値の並びをソートする方法としては速いとは言えないものの、わかりやすいものの一つだと思います。そこで、バブルソートを例に、普通のやりかたと、普通はこうはやらないだろうという例を挙げてみます。   まず、バブルソートというのがどういうものかを簡単に。 [ 2, 8, 9, 5, 7 ] という、数値の並びがあるとします。これを昇順に並べ替える (ソート) したいとします。手順としては、隣り合う値を比べて、必要なら入れ替えるという方法です。 この場合、「2と8では8の方が大きいのでそのままま。8と9では9の方が大きいのでそのまま。9と5では9の方が大きいので、9と5を入れ替える」という手順で行ないます。この段階では、元の並びが、[ 2, 8, 5, 9, 7 ] と変わっています。以後同じように、入れ替えが起こらなくなるまで繰り返します。これが普通のやり方です。 これをPythonのコードで書くと、こんな感じになります: data1 = [5, 9, 2, 1, 3, 7, 6, 4, 8] # 並べ替えの対象となるデータ for j in range(len(data1)-1): for i in range(len(data1)-1):  if i < len(data1) - 1 and data1[i] > data1[i+1]: # A   l = data1[i]   data1[i] = data1[i+1]   data1[i+1] = l print("Current", j, i, data1)print("Result:", data1) これを、ex2.pyという名前で保存して、実行すると、このような結果が得られます (上記コードは本来半角スペースを使うところを、活動報告の制限から全角スペースを使っている箇所があります)。 Current 0 0 [5, 9, 2, 1, 3, 7, 6, 4, 8]Current 0 1 [5, 2, 9, 1, 3, 7, 6, 4, 8]Current 0 2 [5, 2, 1, 9, 3, 7, 6, 4, 8]Current 0 3 [5, 2, 1, 3, 9, 7, 6, 4, 8]Current 0 4 [5, 2, 1, 3, 7, 9, 6, 4, 8]Current 0 5 [5, 2, 1, 3, 7, 6, 9, 4, 8]Current 0 6 [5, 2, 1, 3, 7, 6, 4, 9, 8]Current 0 7 [5, 2, 1, 3, 7, 6, 4, 8, 9]Current 1 0 [2, 5, 1, 3, 7, 6, 4, 8, 9]Current 1 1 [2, 1, 5, 3, 7, 6, 4, 8, 9]Current 1 2 [2, 1, 3, 5, 7, 6, 4, 8, 9]Current 1 3 [2, 1, 3, 5, 7, 6, 4, 8, 9]Current 1 4 [2, 1, 3, 5, 6, 7, 4, 8, 9]Current 1 5 [2, 1, 3, 5, 6, 4, 7, 8, 9]Current 1 6 [2, 1, 3, 5, 6, 4, 7, 8, 9]Current 1 7 [2, 1, 3, 5, 6, 4, 7, 8, 9] [略]Current 6 0 [1, 2, 3, 4, 5, 6, 7, 8, 9]Current 6 1 [1, 2, 3, 4, 5, 6, 7, 8, 9]Current 6 2 [1, 2, 3, 4, 5, 6, 7, 8, 9]Current 6 3 [1, 2, 3, 4, 5, 6, 7, 8, 9]Current 6 4 [1, 2, 3, 4, 5, 6, 7, 8, 9]Current 6 5 [1, 2, 3, 4, 5, 6, 7, 8, 9]Current 6 6 [1, 2, 3, 4, 5, 6, 7, 8, 9]Current 6 7 [1, 2, 3, 4, 5, 6, 7, 8, 9]Current 7 0 [1, 2, 3, 4, 5, 6, 7, 8, 9]Current 7 1 [1, 2, 3, 4, 5, 6, 7, 8, 9]Current 7 2 [1, 2, 3, 4, 5, 6, 7, 8, 9]Current 7 3 [1, 2, 3, 4, 5, 6, 7, 8, 9]Current 7 4 [1, 2, 3, 4, 5, 6, 7, 8, 9]Current 7 5 [1, 2, 3, 4, 5, 6, 7, 8, 9]Current 7 6 [1, 2, 3, 4, 5, 6, 7, 8, 9]Current 7 7 [1, 2, 3, 4, 5, 6, 7, 8, 9]Result: [1, 2, 3, 4, 5, 6, 7, 8, 9] 最後の “Result” の箇所で、昇順にならんでいることが確認出来ます。 なお、ご覧のとおりの無駄は、バブルソートが速くないことの一例です。   では、バブルソートはこのやりかたしか方法はないのでしょうか。たとえばこんなのはどうでしょう。 pat = [ [[2, 1], [1, 2]], [[3, 1], [1, 3]], [[4, 1], [1, 4]], [[5, 1], [1, 5]], [[6, 1], [1, 6]], [[7, 1], [1, 7]], [[8, 1], [1, 8]], [[9, 1], [1, 9]], [[3, 2], [2, 3]], [[4, 2], [2, 4]], [[5, 2], [2, 5]], [[6, 2], [2, 6]], [[7, 2], [2, 7]], [[8, 2], [2, 8]], [[9, 2], [2, 9]], [[4, 3], [3, 4]], [[5, 3], [3, 5]], [[6, 3], [3, 6]], [[7, 3], [3, 7]], [[8, 3], [3, 8]], [[9, 3], [3, 9]], [[5, 4], [4, 5]], [[6, 4], [4, 6]], [[7, 4], [4, 7]], [[8, 4], [4, 8]], [[9, 4], [4, 9]], [[6, 5], [5, 6]], [[7, 5], [5, 7]], [[8, 5], [5, 8]], [[9, 5], [5, 9]], [[7, 6], [6, 7]], [[8, 6], [6, 8]], [[9, 6], [6, 9]], [[8, 7], [7, 8]], [[9, 7], [7, 9]], [[9, 8], [8, 9]]] data1 = [5, 9, 2, 1, 3, 7, 6, 4, 8] for j in range(len(data1)-1): for i in range(len(data1)-1):  if i < len(data1) -1:   data2 = [data1[i], data1[i+1]]  # B   for k in range(len(pat)):    if data2 == pat[k][0]:     # C     data1[i] = pat[k][1][0]     data1[i+1] = pat[k][1][1]     print("FIND", data2, "->", pat[k][1])   print("Current", j, i, data1) print("Result:", data1) これはなにをやっているかというと、まず、入れ替える並びと、それを入れ替えた結果を “pat” という変数に入れています。 また、“# B” のところで、並びの二つ組を作っており、“# C” のところでは、作った二つ組と “pat” の中身を比べています ( [[9, 8], [8, 9]] などの左側、つまり [9, 8] など)。さらに、“# C” の if文の中身で、並びの値を “pat” に基づいて書き換えています ( [[9, 8], [8, 9]] などの右側、つまり [8, 9] など)。 これを実行した結果を見てみましょう: Current 0 0 [5, 9, 2, 1, 3, 7, 6, 4, 8]FIND [9, 2] -> [2, 9]Current 0 1 [5, 2, 9, 1, 3, 7, 6, 4, 8]FIND [9, 1] -> [1, 9]Current 0 2 [5, 2, 1, 9, 3, 7, 6, 4, 8]FIND [9, 3] -> [3, 9]Current 0 3 [5, 2, 1, 3, 9, 7, 6, 4, 8]FIND [9, 7] -> [7, 9]Current 0 4 [5, 2, 1, 3, 7, 9, 6, 4, 8]FIND [9, 6] -> [6, 9]Current 0 5 [5, 2, 1, 3, 7, 6, 9, 4, 8]FIND [9, 4] -> [4, 9]Current 0 6 [5, 2, 1, 3, 7, 6, 4, 9, 8]FIND [9, 8] -> [8, 9]Current 0 7 [5, 2, 1, 3, 7, 6, 4, 8, 9]FIND [5, 2] -> [2, 5]Current 1 0 [2, 5, 1, 3, 7, 6, 4, 8, 9]FIND [5, 1] -> [1, 5]Current 1 1 [2, 1, 5, 3, 7, 6, 4, 8, 9]FIND [5, 3] -> [3, 5]Current 1 2 [2, 1, 3, 5, 7, 6, 4, 8, 9]Current 1 3 [2, 1, 3, 5, 7, 6, 4, 8, 9]FIND [7, 6] -> [6, 7]Current 1 4 [2, 1, 3, 5, 6, 7, 4, 8, 9]FIND [7, 4] -> [4, 7]Current 1 5 [2, 1, 3, 5, 6, 4, 7, 8, 9]Current 1 6 [2, 1, 3, 5, 6, 4, 7, 8, 9]Current 1 7 [2, 1, 3, 5, 6, 4, 7, 8, 9]FIND [2, 1] -> [1, 2]Current 2 0 [1, 2, 3, 5, 6, 4, 7, 8, 9]Current 2 1 [1, 2, 3, 5, 6, 4, 7, 8, 9]Current 2 2 [1, 2, 3, 5, 6, 4, 7, 8, 9]Current 2 3 [1, 2, 3, 5, 6, 4, 7, 8, 9]FIND [6, 4] -> [4, 6]Current 2 4 [1, 2, 3, 5, 4, 6, 7, 8, 9]Current 2 5 [1, 2, 3, 5, 4, 6, 7, 8, 9]Current 2 6 [1, 2, 3, 5, 4, 6, 7, 8, 9]Current 2 7 [1, 2, 3, 5, 4, 6, 7, 8, 9] [略]Current 6 0 [1, 2, 3, 4, 5, 6, 7, 8, 9]Current 6 1 [1, 2, 3, 4, 5, 6, 7, 8, 9]Current 6 2 [1, 2, 3, 4, 5, 6, 7, 8, 9]Current 6 3 [1, 2, 3, 4, 5, 6, 7, 8, 9]Current 6 4 [1, 2, 3, 4, 5, 6, 7, 8, 9]Current 6 5 [1, 2, 3, 4, 5, 6, 7, 8, 9]Current 6 6 [1, 2, 3, 4, 5, 6, 7, 8, 9]Current 6 7 [1, 2, 3, 4, 5, 6, 7, 8, 9]Current 7 0 [1, 2, 3, 4, 5, 6, 7, 8, 9]Current 7 1 [1, 2, 3, 4, 5, 6, 7, 8, 9]Current 7 2 [1, 2, 3, 4, 5, 6, 7, 8, 9]Current 7 3 [1, 2, 3, 4, 5, 6, 7, 8, 9]Current 7 4 [1, 2, 3, 4, 5, 6, 7, 8, 9]Current 7 5 [1, 2, 3, 4, 5, 6, 7, 8, 9]Current 7 6 [1, 2, 3, 4, 5, 6, 7, 8, 9]Current 7 7 [1, 2, 3, 4, 5, 6, 7, 8, 9]Result: [1, 2, 3, 4, 5, 6, 7, 8, 9] ここで “FIND” とあるのは、“pat” にあるものが、対象に見つかったことを示しています。 そして、 “Result” にあるように、やはり並べ替え (ソート) ができています。  2つのやり方を見ましたが、見た目は結構違います。大きな違いは、後者では「見つける並びと、その並べ替えのデータ」を定義していること。そして、前者では値の比較 (“# A” の箇所) と、入れ替えをやっているのに対して、後者では、“pat” の中身に一致するものを探し (“# C” の箇所)、“pat” の中身で置き換えていること。   この2つが大きな違いでしょう。 なお、「“pat” の中身を作るのは大変」と思われるかもしれませんが、それ自体もコンピュータに生成させればいいので、大した問題にはならないことも注意してください。 この例では、並べ替える対象は “[5, 9, 2, 1, 3, 7, 6, 4, 8]” という簡単なデータ構造でした。後者については、“pat” は3次元の配列になっていますが、とくに “[[2, 1], [1, 2]]” のように、「見つける対象」と「入れ替えた結果」というデータ構造を採用しています。 後者はこの「見つける対象」と「入れ替えた結果」というデータ構造を採用することで可能になっています (それが前者よりも効率がいいかはともかく)。 このように、バブルソートという簡単な例でも、その書き方は1つに限らないこと――ここで挙げた2つの他にもありますので考えてみてください――、そしてデータ構造とプログラム――あるいはアルゴリズム――は無関係ではないことを読み取っていただければと思います。