2変数により表示されるような値,例えば座標,などについて網羅的に値を使う
ためにはループを2重にする必要があります.3次元座標であれば3重のループを
扱うこともあるでしょう.座標に限らずテキスト処理でも多重のループが必要に
なるケースは今後たくさん出てきます.ここでは,それらについていくつか試し
てみましょう.
- 基本
まずは,for ループを使用した基本中の基本です.二つのサイコロを
振って出てくる目のパターンを全部表示して見ましょう.
printf "(サイコロ1の目:サイコロ2の目)\n"
for d1 in 1..6
for d2 in 1..6
printf "(%d:%d)\n", d1, d2
end
end
|
全部で36通りの表示ができました.このスクリプトのフローチャートを見てみま
しょう.
図1 サイコロの目のパターン表示の流れ
実際に自分で数値を入れてループをたどってみるのが理解に役立つでしょう.変
数 d1, d2 の両方ともが1に初期化されたあと,d2 に関する
ループが6回回ったら d1 の値が1増えると言うことになります.
再びd2に関するループが6回回り,また,d1が1増えます.d2ループが6回回る毎にd1が1
増えるの繰り返しです.
サイコロが3個になったらどのようになるのか,自分で試してみましょう.
- while 文への変更
while ループを使って今のスクリプトを書き直してみましょう.
printf "(サイコロ1の目:サイコロ2の目)\n"
d1 = 1
while d1 <= 6
d2 = 1
while d2 <= 6
printf "(%d:%d)\n", d1, d2
d2 += 1
end
d1 += 1
end
|
while ループを使う方がフローチャートに近い処理になっています.
- 繰り返し条件の動的設定
サイコロの目の例についてもう少し考えてみましょう.先ほどは,サイコロ1と
サイコロ2の目のパターンを表示しましたが,単に二つのサイコロの目のパター
ンとして考えると,(1:2)と(2:1)は同じものになります.順列と組合せの関係で
す.では,この組合せを表示するためにはどうすれば良いのか,次の例で見てみ
ましょう.
printf "(サイコロ1の目:サイコロ2の目)\n"
for d1 in 1..6
for d2 in d1..6
printf "(%d:%d)\n", d1, d2
end
end
|
この例では内側のループの開始条件が外側のループの変数 d1 に依存
しています.既に終わった組合せを取り除くために重複部分を避けています.こ
のような例も良く利用されます.
目の組合せは全部で21通りありました.この答えを組合せの計算から出してみる
のも数学の勉強になるでしょう.
- 行列要素
行列の要素を一般的に表現するのに,図2のような添字(Suffix)を用いて
表します.
A11 A12 A13
A21 A22 A23
A31 A32 A33
A41 A42 A43
|
図2 行列の一般的な要素表現
これを実現するスクリプトは以下のような例が考えられます.
for i in 1..4
for j in 1..3
printf "A%d%d ", i, j
end
printf "\n"
end
|
ARGV を用いて,任意の行数と列数で表示できるように変更してみましょ
う.
このように文字列や数字を2次元的に配置するためには,2重のループを使うと効
率良く表せます.上の例程度であれば,
for i in 1..4
printf "A%d1 A%d2 A%d3\n", i, i, i
end
|
というように一つのループでも表現できますが,要素の数が増えると現実的では
無くなります.
- 6桁の乱数発生
以前にロト6風の数当てゲームを作りました.そのときに6桁の乱数を発生させ
るために,桁数が少ない場合を想定して0を補う処理を用意しました.ループを
使うとそのような心配は無くなります.
num = ""
for n in 1..6
num += rand(10).to_s
end
puts num
|
多重のループでは無いですが,これもループの応用例の一つです.
- 例題1
トランプ52枚のマークと数字のパターンを全て表示するスクリプトを考えましょ
う.マークは4種類,数字は13種類です.外側のループをマーク,内側を数字で
作ります.
- 例題2
3つの負でない整数h,k,lを考えます.それぞれ最大値を4として,h+k+lが偶数
になるパターンを全て表示してみましょう.また,hklが全て偶数か全て奇数か
の場合(偶奇混合なし)を全て表示することも試してみましょう.これは,物性や材料分野で必須
の結晶構造に関する重要な問題です.
ループが3重になります.どの順で回しても良いですが,通常はhklの順に内側に
入って行く形式でしょう.