第4章の練習,投票


復習:真偽値を返す関数

def divisible(x,y)
   x%y==0
end


次の結果は何?

irb(main):001:0> divisible(111111111,9)
  1. true
  2. false
  3. 0
  4. 12345679
  5. 8

繰り返しによる和の定義

def sum_loop(n)
  s = 0
  for i in 1..n
    s = s+i
  end
  s
end

条件を満たす値を探す繰り返し

def gd_loop(k,n)
  while !divisible(k,n)
    n=n-1
  end
  n
end

次の結果は何?

gd_loop(1234567,1234566)
  1. 3
  2. 11
  3. 127
  4. 9721
  5. 11111

再帰による反復計算の定義 -- 再帰による和の定義

def sum(n)
  if n>=2
    sum(n-1)+n
  else
    1
  end
end

約数の和

load("./divisible.rb")
def sod(k,n)
  if n>=2
    if divisible(k,n)
      sod(k,n-1)+n
    else
      sod(k,n-1)
    end
  else
    1
  end
end

練習

        0    (k > n のとき)  
nCk = { 1    (k = 0 のとき)
        n-1Ck-1 + n-1Ck ( それ以外)


進捗状況の確認

combination(5,3) -> 10
combination(10,5) -> 252

条件を満たす値を探す

load("./divisible.rb")
def gd(k,n)
  if divisible(k,n)
    n
  else
    gd(k,n-1)
  end
end

配列の作成と操作

def make1d(n)
  a = Array.new(n)
  for i in 0..(n-1)
    a[i] = 0
  end
  a
end
load("./make1d.rb")
def make2d(height,width)
  a = Array.new(height)
  for i in 0..(height-1)
    a[i] = make1d(width)
  end
  a
end

繰り返しによる組み合わせ数の計算

def combination_loop(n,k) 
  c=make2d(n+1,n+1) 
  for i in 0..n
    c[i][0] = 1 
    for j in 1..(i-1)
      c[i][j] = c[i-1][j-1] + c[i-1][j] 
    end
    c[i][i] = 1 
  end
  c[n][k] 
end

次の結果は何?

combination_loop(40,32)
  1. 40
  2. 91390
  3. 76904685
  4. 137846538820
  5. 12641060643775

言葉探し

def submatch(s,i,p,w)
  j=0
  while j< w && s[(i+j)..(i+j)]==p[j..j]
    j=j+1
  end
  j
end
def match(s,p)
  i=0
  w=p.length()
  while submatch(s,i,p,w)< w
    i=i+1
  end
  i
end

練習

matchの定義ではs中にpが必ず現れることを仮定していた.pが現れない 場合に-1と答えるmatch_safe(s,p)を定義せよ
ヒント
submatchの定義は変更しないでそのまま使って良い.
def match_safe(s,p)
  i=0
  w=p.length()
  while i<=s.length()-w && submatch(s,i,p,w)< w
    i=i+1
  end
  if i<=s.length()-w
    # 見つかった時には何を返す?
  else
    # 見つからなかった時には何を返す?
  end
end

進捗状況の確認

  1. match_safe(s,p) ができた時点で投票してください。
    match_safe("abra","ra") -> 2
    match_safe("abca","ra") -> -1
    
    となることを確認してください.

第1-4章まとめ課題


昨年度の作品

昨年度の作品が第1-4章まとめ課題にあります.

ヒント

一から作るのが面倒な人は,以下のプログラムの(1)の部分の穴を埋めて a[y][x]に点(x,y)でのR,G,B値からなる大きさ3の配列を入れるコードを書く ので良い.
include Math
load("./make2d.rb")
def show_color_picture()
  a=make2d(50,50)
  for y in 0..49
    for x in 0..49
# 穴を埋める.
#a[y][x]にRGB値からなる大きさ3の配列(要素は0から1までの実数)を入れる
       (1)
    end 
  end
  show(a)
end
たとえば,(1)のところに
      a[y][x]=[x/49.0,1.0-y/49.0,1.0]
と入れると, になり,その間を補間した

のような図が得られる.

ヒント

乱数を使いたい人はrand(n)で0以上n-1以下の整数が返る.
irb(main):014:0> rand(3)
=> 1
irb(main):015:0> rand(3)
=> 2
irb(main):016:0> rand(3)
=> 0
実数の乱数は rand() で0.0以上1.0以下の一様乱数が返る.
irb(main):017:0> rand()
=> 0.65583344076718
irb(main):018:0> rand()
=> 0.336235732920702
irb(main):019:0> rand()
=> 0.324077367496

実数値を整数値に変換するには,「式」の後に .to_i() をつける.
irb(main):020:0> x=2.9
=> 2.9
irb(main):021:0> x.to_i()
=> 2
irb(main):022:0> x=-2.9
=> -2.9
irb(main):023:0> x.to_i()
=> -2
四捨五入ではないので,注意が必要.

ヒント

画像ファイルをrubyの配列にするには,一旦 convertコマンド を使って,テキストエディタで見える形式にするのが楽だろう. というPNG形式の画像ファイルがある時,
convert globe.png -compress none globe.ppm
を実行すると,以下のようなテキスト形式のファイル globe.ppm が作られる.
P3
34 42
255
246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 246 
....
246 246 246 246 246 246 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 245 
このファイル形式はPNM(Wikipedia) のように扱いやすいので,これをテキストエディタで編集して,rubyの配列の初期化の形に修正すると楽と思われる.