情報科学概論
2003.7.1

Back to index page



  1. 本日の作業内容

  2. 制御構造 (繰り返し3)

    • until ループの基礎

      先週学習した while ループにおいては,条件式が真である限り繰り返 しを続けましたが,ここで紹介する until は条件式が偽である限り処 理を続けるものです.単純な例で見てみましょう.

      i = 1
      
      until i > 10
        puts i
        i += 1
      end
      

      同様の処理を while を用いて行うならば,条件式の不等号が逆になり ます.

      if に対する unless があったように,while に対 して until があります.活用するかどうかはスクリプト次第 ですが,この授業で紹介しているような単純な条件式では until で無ければならない,もしくは,until の方が便利,と 言う状況にはならないでしょう.当面は,while だけで十分 です.ただし,存在くらいは知っておきましょう.

    • 多重ループの活用

      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の順に内側に 入って行く形式でしょう.

  3. 小テスト

    授業の残り20分くらいでAクラスBクラス別々の小テストを行いますので,アナウンス に注意してください.

  4. 宿題

    授業の最後にAクラスBクラス別々の宿題の案内も出しますので,アナウンスに注意してください.


目次ページに戻る