Hatena::Grouprubyist

Ruby初心者prinyの学習帳 RSSフィード

2009-01-15練習:たのしいRuby

P.203 (1) square メソッドを定義する

17:57

数値からなる配列 nums に対して、その個々の要素を自乗した要素からなる
配列を返すメソッド square を 3 通りの方法で定義しましょう。

(a) collect を使う

def square1(nums)
  nums.collect{|i| i**2 }
end

nums = [1, 3, 5, 7, 9]
p square1(nums)

実行結果

[1, 9, 25, 49, 81]

(b) collect は使わず、each を使う

def square2(nums)
  result = []
  nums.each{|i|
    result << i**2
  }
  return result
end

nums = [2, 4, 6, 8, 10]
p square2(nums)

実行結果

[4, 16, 36, 64, 100]

(c) collecteach も使わず、インデックスと[ ]を使う

def square3(nums)
  nums.each_index{|index|
    nums[index] **= 2
  }
end

nums = [1, 9, 25, 49, 81]
p square3(nums)

実行結果

[1, 81, 625, 2401, 6561]

P.203 (2) sum_array メソッドを定義する

17:57

数値からなる配列 nums1 と nums2 に対して、それらの個々の要素を足し合わせた
要素からなる配列を返すメソッド sum_array を定義しましょう。

書いたもの

def sum_array(ary1, ary2)
  result = []
  ary1.zip(ary2){|a, b|
    result << a + b
  }
  return result
end


nums1 = [1, 2, 3]
nums2 = [4, 5, 6]
p sum_array(nums1, nums2)

実行結果

[5, 7, 9]

rochefort さんの日記 を見て、zipmap を使えば、もっとすっきり書けることを知った。なるほどねぇ。

あと、ためしに、要素数が異なる配列を足してみた。案の定、ary1 のほうが少ないときは ary1 と同じ要素数の配列が返ってきたけど、ary1 のほうが多いときは、nilFixnum は足せないよ、というエラーが返ってきた。

このメソッドで足せるかどうかを事前にチェックすることも考えた。チェックするなら、配列の要素数が同じか、と、配列の要素が数値オブジェクトだけか、の 2 つかな。でも、チェックを入れると、その分、sum_array するのに時間がかかるし、いまいちかも。で、やっぱり、要素数が異なる配列を足そうとしたときなどのエラーは、実行時のエラーにお任せすることにした。


P.203 (3) balanced? メソッドを定義する

17:57

(, ), {, }  という 4 つの文字を要素とした配列がある。この配列に対して、
カッコが正しく対応しているかを調べるメソッド balanced? を定義しましょう。
「カッコが正しく対応している」とは、以下のような状態のことです。
 ・( と ) の数が同じ
 ・{ と } の数が同じ
 ・「( )」の対応と「{ }」の対応が交差することはない

書いたもの 1

正規表現を使ってみた。

def balanced?(ary)
  str = ary.join
  while (/\(\)/ =~ str) || (/\{\}/ =~ str)
    result = str.gsub!(/\(\)|\{\}/, "")
  end

  if result == ""
    return true
  else
    return false
  end
end

p balanced?(%w! ( !)
p balanced?(%w! { } !)
p balanced?(%w! ( { { } ( ) } ( ) ) !)
p balanced?(%w! ( { { ( } ( ) } ( ) ) !)

実行結果

false
true
true
false

書いたもの 2

今度は、スタックを使って。

def balanced2?(ary)
  stack = []
  ary.each {|elem|
    case elem
    when "("
      stack << elem
    when "{"
      stack << elem
    when ")"
      if stack.last != "("
        return false
      else
        stack.pop
      end
    when "}"
      if stack.last != "{"
        return false
      else
        stack.pop
      end
    else
      return false
    end
  }
  
  if stack.size == 0
    return true
  else
    return false
  end
end

p balanced2?(%w! ( !)
p balanced2?(%w! { } !)
p balanced2?(%w! ( { { } ( ) } ( ) ) !)
p balanced2?(%w! ( { { ( } ( ) } ( ) ) !)

実行結果

false
true
true
false

holysugarholysugar 2009/01/15 18:41 square3 は、引数を直接書き換えてるので nums が変わってしまってるのに注意。意図してないなら dup しましょう。

prinypriny 2009/01/16 12:16 コメントをありがとうございます。

引数 nums を書き換えることは意図したことではないです。手元のものは以下のように修正しました。
def square3(nums)
copy = nums.dup
copy.each_index{|index|
copy[index] **= 2
}
end

蛇足ですが、square3 は、最初はこんなふうに書いていました。
def square3(nums)
indexes = (0...nums.size).to_a
result = []
while index = indexes.shift
result << nums[index] ** 2
end
return result
end

これなら、nums を書き換えてはいなかったです。
インデックスの配列をわざわざつくらなくても、Ruby にはインデックスに対して何かをするメソッドがあるのではと思っていたところ、Array#each_index を見つけ、これを使いました。
マニュアルを読んで使い方を理解したつもりだったのですが、まだまだですね。

JaylynJaylyn 2011/09/07 23:20 For the love of God, keep wrtinig these articles.

dpjpqedpjpqe 2011/09/08 17:10 ixKdgy <a href="http://xdjlmaumrzcn.com/">xdjlmaumrzcn</a>

imxcoxzuoaimxcoxzuoa 2011/09/08 21:20 BJJecy , [url=http://iqgvfnjxkrzr.com/]iqgvfnjxkrzr[/url], [link=http://sfennuokytve.com/]sfennuokytve[/link], http://fqcppptoavml.com/

ddoswzjzmlfddoswzjzmlf 2011/09/10 22:29 WSfJpC , [url=http://vvcezykqtqef.com/]vvcezykqtqef[/url], [link=http://swrdvfffiyzf.com/]swrdvfffiyzf[/link], http://cuhxnihbjgsq.com/

ゲスト



トラックバック - http://rubyist.g.hatena.ne.jp/priny/20090115