sin5のRuby勉強日記 このページをアンテナに追加 RSSフィード

2006-06-26

[]11_1 二乗の配列を返すメソッド 11_1 二乗の配列を返すメソッド - sin5のRuby勉強日記 を含むブックマーク はてなブックマーク - 11_1 二乗の配列を返すメソッド - sin5のRuby勉強日記 11_1 二乗の配列を返すメソッド - sin5のRuby勉強日記 のブックマークコメント

最初に

せっかくなので

http://rubyist.g.hatena.ne.jp/secondlife/20060516/1147792077

を参考にTDDにチャレンジしてみることにした。

問題

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

  • (a)collectを使って定義する
  • (b)collectは使わず、eachを使って定義する
  • (c)collecteachも使わず、インデックスと[]を使って定義する。

p square([1, 2, 4, 6]) #=> [1, 4, 16, 36]

解答

require 'test/unit'

class SquareTest < Test::Unit::TestCase
  def setup
    @arg = [1,2,4,6]
    @result = [1,4,16,36]
  end

  def test_a
    assert_equal square_a(@arg), @result
  end

  def test_b
    assert_equal square_b(@arg), @result
  end

  def test_c
    assert_equal square_c(@arg), @result
  end
end

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

def square_b(nums)
  result = Array.new
  nums.each{|i| result.push(i ** 2)}
  result
end

def square_c(nums)
  result = Array.new
  nums.size.times{|i| result[i] = nums[i] ** 2}
  result
end

結果

Loaded suite 11_1
Started
...
Finished in 0.003392 seconds.

3 tests, 3 assertions, 0 failures, 0 errors

コメント

なんか癖でArray.newとか書いちゃうけど[]の方がカコイイ気がする。

これも気分の問題だけどcollectよりmapの方が気持ちがいい。

[]11_2 配列の個々の要素を足し合わせた配列を返すメソッド 11_2 配列の個々の要素を足し合わせた配列を返すメソッド - sin5のRuby勉強日記 を含むブックマーク はてなブックマーク - 11_2 配列の個々の要素を足し合わせた配列を返すメソッド - sin5のRuby勉強日記 11_2 配列の個々の要素を足し合わせた配列を返すメソッド - sin5のRuby勉強日記 のブックマークコメント

問題

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

解答

require 'test/unit'

class SumArrayTest < Test::Unit::TestCase
  def setup
    @arg1 = [1, 2, 3]
    @arg2 = [4, 6, 8]
    @result = [5, 8, 11]
    @arg3 = [1, 2, 3]
    @arg4 = [1, 2, 3, 4]
    @result2 = [2, 4, 6, 4]
  end

  def test_sum_array
    assert_equal sum_array(@arg1, @arg2), @result
    assert_equal sum_array(@arg3, @arg4), @result2
  end
end

def sum_array(nums1, nums2)
  num = (nums1.size >= nums2.size) ? nums1.size : nums2.size
  Array.new(num){|i|
    if !nums1[i]
      nums2[i]
    elsif !nums2[i]
      nums1[i]
    else
      nums1[i] + nums2[i]
    end
  }
end

結果

Loaded suite 11_2
Started
.
Finished in 0.002241 seconds.

1 tests, 2 assertions, 0 failures, 0 errors

コメント

はいはいはいはい。馬鹿な書き方してごめんなさい。たのしいRubyに1.8ではArray.newにブロックが渡せると書いてあったので使ってみたかっただけですよ。

遅くにはじめた利点…このグループに同じ問題解いてる人がいること!!!

自分が解いた後に他の人の解答を見るといろいろと参考になってイイ。

(自分が解く前に他の人の解答を見ないようにしなきゃいけないというところもありますけどね…)

secondlifeさんの

http://rubyist.g.hatena.ne.jp/secondlife/20060516/1147793624

zipなんて全然知らなかったので目から鱗。

[]11_3 カッコの配列が正しく対応しているかを調べるメソッド 11_3 カッコの配列が正しく対応しているかを調べるメソッド - sin5のRuby勉強日記 を含むブックマーク はてなブックマーク - 11_3 カッコの配列が正しく対応しているかを調べるメソッド - sin5のRuby勉強日記 11_3 カッコの配列が正しく対応しているかを調べるメソッド - sin5のRuby勉強日記 のブックマークコメント

問題

(,),{,}という4つの文字を要素とした配列があります。この配列に対して、カッコが正しく対応しているかどうかを調べるメソッド、balanced?メソッドを定義してください。なお、「カッコが正しく対応している」とは

  • (と)の数が同じ
  • {と}の数が同じ
  • 「()」の対応と「{}」の対応が交差することはない

といった状態のことです

解答

require 'test/unit'

class BlancedTest < Test::Unit::TestCase
  def setup
    @arg1 = %w[( ) ( ) { ( ) ( ( { } ) ) }]
    @arg2 = %w[( ) ( ( ) { } ) ) )]
  end

  def test_blanced
    assert blanced?(@arg1)
    assert !blanced?(@arg2)
  end
end

def blanced?(arr)
  list = {
    ')' => '(',
    '}' => '{'
  }
  stack = []
  arr.each{|case_arc|
    open = true
    list.keys.each{|close|
      if(case_arc == close)
        return false if stack.pop != list[case_arc]
        open = false
        break
      end
    }
    stack.push(case_arc) if open
  }
  return (stack.size == 0) ? true : false
end

実行結果

Loaded suite 11_3
Started
.
Finished in 0.002555 seconds.

1 tests, 2 assertions, 0 failures, 0 errors

コメント

なんか今までのより難しかった。

その分他の人のプログラムと差ができていておもしろい。

secondlifeさんの

    case item
    when *pair.values
      stack.push item
    when *pair.keys
      return false unless stack.pop == pair[item]
    else
      return false
    end

がカッコイイ

whenには複数の引数を与えることができて、配列に*を使って複数の引数に変えるわけか…調べないと意味がわからなかった。

最後はempty?を使えば三項演算子なんか使う必要はなかったわけか。

トラックバック - http://rubyist.g.hatena.ne.jp/sin5/20060626