2016-05-03 10 views
3

クラスイメージは、0と1の配列を初期化します。私はこの方法transform、このよう反復は

[[0,0,0], 
[0,1,0], 
[0,0,0]] 

戻り

[[0,1,0], 
[1,1,1], 
[0,1,0]] 

私はこれを反復n回変換して、メソッドブラー(n)を実装したい、

[[0,0,0,0,0,0,0,0,0], 
[0,0,0,0,0,0,0,0,0], 
[0,0,0,0,1,0,0,0,0], 
[0,0,0,0,0,0,0,0,0], 
[0,0,0,0,0,0,0,0,0]] 
と、このような呼び出しぼかし(2)それを持っています

戻り

[[0,0,0,0,1,0,0,0,0], 
[0,0,0,1,1,1,0,0,0], 
[0,0,1,1,1,1,1,0,0], 
[0,0,0,1,1,1,0,0,0], 
[0,0,0,0,1,0,0,0,0]] 

私はこれを達成するために反復変換を使用しようとしていますが、Imageのインスタンスでblurを呼び出すときにはundefined method 'map' for #<Context::Image:0x000000012eb020>になります。どのようにぼかしが最大n回の変換で最新のバージョンを返すように、各連続変換に対して繰り返し処理できますか?

class Image 
    attr_accessor :array 

    def initialize(array) 
    self.array = array 
    end 

    def output_image 
    self.array.each do |item| 
     puts item.join 
    end 
    end 

    def transform #changes adjacent a 1's adjacent 0's into 1 
    cloned = self.array.map(&:clone) 

    #scan original array for 1; map crosses into clone if found 
    self.array.each.with_index do |row, row_index| 
     row.each.with_index do |cell, col| 
     if cell == 1 
      cloned[row_index][col+1] = 1 unless col+1 >= row.length #copy right 
      cloned[row_index+1][col] = 1 unless row_index+1 >= cloned.length # copy down 
      cloned[row_index][col-1] = 1 unless col.zero? # copy left 
      cloned[row_index-1][col] = 1 unless row_index.zero? #copy up 
     end 
     end 
    end 
    cloned 
    end 

    def blur(n) #should call transform iteratively n times 
    blurred = Image.new(self) 
    n.times do 
     blurred = blurred.transform 
    end 
    blurred 
    end 

end 

答えて

1

Matrixクラスを使用できます。

require 'matrix'  

class Matrix 
    def el(r,c) 
    if r < 0 || r >= row_count || c < 0 || c >= column_count 
     0 
    else 
     self[r,c] 
    end 
    end 

    def transform 
    Matrix.build(row_count, column_count) { |r,c| 
     [el(r,c), el(r-1,c), el(r+1,c), el(r,c-1), el(r,c+1)].max } 
    end 
end 

行 - 列ペア、r, c、行または列が行列さもなければ[r,c]における値の範囲外である場合は0を返すelヘルパーメソッドが与えられます。

nrows = 5 
ncols = 5 

m = Matrix.build(nrows, ncols) { |r,c| (r==nrows/2 && c==ncols/2) ? 1 : 0 } 
    #=> Matrix[[0, 0, 0, 0, 0], 
    #   [0, 0, 0, 0, 0], 
    #   [0, 0, 1, 0, 0], 
    #   [0, 0, 0, 0, 0], 
    #   [0, 0, 0, 0, 0]] 
m = m.transform 
    #=> Matrix[[0, 0, 0, 0, 0], 
    #   [0, 0, 1, 0, 0], 
    #   [0, 1, 1, 1, 0], 
    #   [0, 0, 1, 0, 0], 
    #   [0, 0, 0, 0, 0]] 
m = m.transform 
    # Matrix[[0, 0, 1, 0, 0], 
    #   [0, 1, 1, 1, 0], 
    #   [1, 1, 1, 1, 1], 
    #   [0, 1, 1, 1, 0], 
    #   [0, 0, 1, 0, 0]] 
m.to_a 
    #=>  [[0, 0, 1, 0, 0], 
    #   [0, 1, 1, 1, 0], 
    #   [1, 1, 1, 1, 1], 
    #   [0, 1, 1, 1, 0], 
    #   [0, 0, 1, 0, 0]] 
1

mapArrayにではなく、カスタムクラスImageに利用できる方法です。

私の代わりに@array変数インスタンスにmapを呼び出すことをお勧めします。次に、変換が完了したら、変換された配列を持つ新しいImageインスタンスを作成します。

以下は動作するはずのコードの例です。 transformとblurは入力配列をパラメータとして取るため、インスタンスの状態に依存しないことに注意してください。したがって、私はそれらにインスタンスメソッドの代わりにクラスメソッドを作成しました。これにより、インスタンスを作成することなくユーザーが使用できるようになります。実行したいのは配列変換だけです。また、これらのメソッドを将来のリファクタリングでモジュールに簡単に抽出できるようにします。インスタンスメソッド、blurred_imageを追加しました。このメソッドは、インスタンスに変換を適用し、新しいImageインスタンスを返します。

def self.transform(input_array) #changes adjacent a 1's adjacent 0's into 1 
    cloned = input_array.map(&:clone) 

    #scan original array for 1; map crosses into clone if found 
    input_array.each.with_index do |row, row_index| 
     row.each.with_index do |cell, col| 
     if cell == 1 
      cloned[row_index][col+1] = 1 unless col+1 >= row.length #copy right 
      cloned[row_index+1][col] = 1 unless row_index+1 >= cloned.length # copy down 
      cloned[row_index][col-1] = 1 unless col.zero? # copy left 
      cloned[row_index-1][col] = 1 unless row_index.zero? #copy up 
     end 
     end 
    end 
    cloned 
    end 

    def self.blur(input_array, transform_count) #should call transform iteratively n times 
    blurred = input_array 
    transform_count.times { blurred = transform(blurred) } 
    Image.new(blurred) 
    end 

    def blurred_image(transform_count) 
    self.class.new(self.class.blur(array, transform_count)) 
    end