Ruby: Ruby入門とプログラム練習

ここではRubyの文法とプログラミングの練習を行う。

以下、例を中心にRuby言語の基本を説明する。 細いことは説明しないので、適宜参考文献を見て欲しい。 使う構文は厳選する。

自宅で使う場合はRubyのインストール方法を見てください。

最初のプログラム、実行

Rubyのプログラムは
print "Hello, Yamaguchi\n"
のような形式である。

プログラムを実行する方法はRubyを動かしてみようを参照せよ。 以下でサンプルプログラムが用意されている場合があるが、その場合はプログラムを(右ボタンなどで)ダウンロードして、 Rubyを動かしてみようの(2)の方法で実行してみよ。 例えば、上のサンプルプログラムhelloyamaguchi.rbをダウンロードして実行してみよ。

上のプログラムを「実行」すると「print "Hello, Yamaguchi\n"」が実行されて、「Hello, Yamaguchi」が表示される。 \nは改行の指定である。 「"..."」は文字列である。「"」で囲わないと...をいろいろに解釈して計算してしまう。 「print "Hello, Yamaguchi\n"」は「文」の一種である。 プログラムを「実行」すると、プログラムのなかの文を(複数あれば順に)実行する。

変数

データの入れ物が変数である。 変数は名前をつけて使う。これを変数名という。 変数名は英字で始まる英数字の列である。大文字と小文字は区別する。 「_」など英数字以外にもいくつか許される文字がある。 途中に空白を入れてはいけない。

変数は次のように使う。
i = 2

これを、変数に値を代入するという。変数iの値を2に変更するので、これを実行した後で、iの値を使おうとすると2が使われる。
print i*i

式のなかに変数を書くと計算ではその変数に(直前に)代入された値を使う。
i = i + 1

代入は数学の恒等式とは違い、右辺を計算して、その値を左辺の変数に代入する。 上の代入ではiの値が1増える。
i += 1
i = i + 1と同じ。

Rubyでは変数に、整数でも実数でも代入することができる。 整数を代入した後で実数を代入したり、その逆もできる。

変数にはオブジェクトも代入できる

変数名の先頭が大文字の場合は代入が一度しかできない。 これは定数を定義するために使う。

式には次のようなものがある。

四則演算は+, -, *, /で表す。 数学の記法と違い乗算も省略しない。*と/は+と/より優先する。()で囲んだ部分は先に計算する。 結合は左から右。つまり、1-2-3は(1-2)-3と解釈する。

数には整数と実数がある。Rubyでは整数には上限や下限はない。(多倍長計算といって、自動的に桁を増やす。) 実数は10進数で16桁程度の精度である。

整数を整数で割ると整数の割り算を行い商を求める。つまり、2/3は0となるので注意すること。 整数の割り算では余りを求める演算子(%)がある。%は意外によく使う演算子である。

y == 2007
==は比較演算である。結果はtrueかfalseのどちらか。 yの値と2007が等しい時にtrue、等しくなければfalseとなる。これはtrueかfalseだけを値として取るboolean(真偽値)という種類(型)のデータである。 「==」以外の比較演算としては、等しくない「!=」、大きい「>」、大きいか等しい「>=」、小さい「<」、小さいか等しい「<=」がある。

booleanのデータに対する演算子に&&(積)、||(和)、!(否定)がある。

y == 2007 && m == 2
yが2007でmが2の時だけtrueとなる。

1 <= x && x <= 10
の時だけtrueとなる。 (1 <= x <= 10とは書けないので注意)

ビット演算

文字列に対しては「+」は文字列の結合の演算となる。
"1"+"2"
この計算結果は"12"となる。

配列

沢山のデータを入れられる入れものを配列という。 沢山のデータから一つ選ぶには添字をつかう。添字は0から始まる自然数で、[]で囲ってつける。

a = [1,2,3]
a[0]が1、a[1]が2、a[2]が3の配列を作る。

a[0] = -1
a[0]が-1となる。a[0]以外は変化しない。

aが配列でない時に要素に代入しようとするとエラーになる。 そのようば場合は、以下のように空の配列としておいてから、要素に代入する。
a = []

m.length
配列の大きさ。

型の変換

文字列の"1"と整数の1は扱いが違うので、必要に応じて型を変換する必要がある。

制御構造

条件に応じて文の実行順序を制御することができる。

IF

if 条件(booleanの値になる式)
 条件が成りたったら実行する文
end

一回の条件判断で成り立つ場合とそうでない場合に振り分けることができる。
if 条件(booleanの値になる式)
 条件が成り立ったら実行する文
else
 条件が成り立たなかったら実行する文
end

条件が成り立たない場合更に他の条件で場合分けすることができる。
if 条件(booleanの値になる式)
 条件が成り立ったら実行する文
elsif 次の条件
 次の条件が成り立ったら実行する文
elsif 更に次の条件
 更に次の条件が成り立ったら実行する文
else
 どれも成り立たなかったら実行する文
end

if year % 4 == 0
 print "leap year\n"
end
yearが4の倍数の時だけ表示をする。ifの後の式はbooleanでないといけない。

if i > 0
 print "plus\n"
elsif i == 0
 print "zero\n"
else
 print "minus\n"
end
elsifの後に次の条件を書く事ができる。

if year % 4 == 0
 leapYear += 1
 print "leap year\n"
end
endまでの間に複数の文を書くと順に実行される。

FOR

指定された回数、文を実行する事ができる。 回ごとに指定された変数の値が変わって行くので、それを使ってその回の計算巣をする。
for 変数 in 始点..終点
 変数=始点, 始点+1, ..., 終点に対して実行する文
end

for i in 0..4
 print i," ",i*i,"\n"
end
i = 0,1,2,3,4に対して、「print i," ",i*i,"\n"」を実行する。

for i in 1..9
 for j in 1..9
  print i*j," "
 end
 print "\n"
end
(i,j)は(1,1),(1,2),...,(1,9),(2,1),...のように内側のjが速く変化する。

WHILE

回数を定めず、条件が成り立たなくなるまで繰り返す。
while 条件
 条件が成り立っている間繰り返し実行する文
end

i = 13
while i != 1
 if i%2 == 0
  i /= 2
 else
  i = 3*i + 1
 end
 print i,"\n"
end
「while(A) B」で、A、B、A、B、A、B、...のように計算/実行する。Aの計算結果がfalseになったら終了する。 これはコラッツの予想を13について確かめるもの。

入力

gets
キーボードから1行入力する。入力した文字列を返す。
ARGV
「ruby ファイル名 a1 a2 ...」のように実行されると、a1,a2,...,が文字列の配列としてARGVに入る。

メソッド

一連の処理をまとめて、一括で呼び出せるようにする。
def repeat(n)
 for i in 1..n
  print "*"
 end
end
()中は引数。呼び出す側の引数は実引数、メソッドの定義の引数は仮引数という。 「repeat(10)」と実行すると実引数の10が仮引数のnに代入されて、for文が実行される。 for文の実行が終わるとそれ以上する事がないので、「repeat(10)」と実行が終了して、次の文の処理に移る。

def half(i)
 i/2
end
「n = half(5)」のように式の中で使うと式を計算する時に呼び出されるメソッド。 i/2の値が返るので、その値がnに代入される。

メソッドのなかで始めて使われた変数は、メソッドの中でだけ有効。 メソッドの外で使われた変数は同じクラスの他のメソッドから見える。

Rubyのプログラムの例

文字化けする場合はブラウザのテキストエンコーディングをUnicode(UTF-8)に変更してみてください。

  1. 摂氏華氏変換
    サンプルプログラム3-11.rb

    「ruby 3-11.rb 37」のように実行すると、37を華氏に変換して表示する。

  2. 最大値の計算
    サンプルプログラムmax.rb

    与えられた整数の配列のなかで最大の要素の位置(先頭は0)と値を表示する。

  3. 文字列のマッチング
    サンプルプログラム4-10.rb

    "uraniwaniwaniwaniwatoriairu"のなかから"waniwaniwato"を見つける。 matc_at(s,p,i)はsのi文字目からpがあるかを調べるメソッド。

  4. ライフゲーム
    サンプルプログラムlife.rb

    ライフゲームのシミュレーションプログラム。グライダーと名付けられたパターンが"飛ぶ"。

Rubyのプログラムの練習

どれをやるかは教員の指示に従ってください。

  1. 矢印
    次のような矢印を表示するプログラムを作る。大きさを指定できるようにする。
             *
            ***
           *****
          *******
         *********
        ***********
       *************
      ***************
     *****************
    *******************
             *
             *
             *
             *
             *
             *
             *
             *
             *
             *
    

  2. ジャンケン
    ジャンケンゲームで次の動作をするプログラムを作る。

    コンピュータは人間の前回と前々回の手を記憶しておき、

    と推測し、それに勝つ手を選ぶ。

    例えば、

    である。

  3. 日数計算
    年月日で与えられた2つの日の間(片方は含めるので翌日の場合は1日と数える)の日数を計算するプログラムを作る。

  4. 割り当て
    劇団員に役の割り当てをするプログラムを作る。

    劇団員は、東大太郎、赤門花子、銀杏冴子の3名からなる。 役は、千尋、湯婆婆、番台蛙からなる。 赤門花子が千尋なら東大太郎は湯婆婆はやりたくないといっているので、 その条件を満たすような割り当てを全て表示する。

  5. 暗号
    シーザー暗号解読のプログラムを作る。

    シーザー暗号は次の通り。

    プログラムを作成して暗号を復号せよ.(「"」は区切りであり文字列の一部ではない。) 鍵は不明であるが,復号した平文には"person"が含まれていることが分かっているとする.

  6. あみだくじ
    あみだくじの作り込みをする。

    n0,n1,...nN-1を指定して、 そのあみだくじを通すと0〜N-1がn0,n1,...nN-1に入れ替わるようなあみだくじを作る。

  7. 順列生成
    指定されたNに対して、0〜N-1の全ての順列を生成する。

yamaguch@mail.ecc.u-tokyo.ac.jp
Copyright 2011 Kazunori Yamaguchi 山口和紀@東京大学総合文化研究科