0

マトリックス内の特定のセルまたはセルのセットの隣にあるすべてのポイントを識別することに関して質問がありました(マトリックスの要素が別の要素に「接触」していることを確認するためのRubyの方法が必要ですを参照)。適切なアイデアが出されなかったので、ブルートフォースで進めることにしました。

以下のコードは、私がやろうとしていたことをうまく実行します。配列tmpl(テンプレート)には、特定の座標(atlantisによって提供される)からその周囲の8つのセルに到達する方法のマップが含まれています。次に、アトランティスの各要素をtmplのすべての要素と合計することにより、アトランティスの海岸線に接するすべての「水中」の土地を含む配列sl(海岸線)を作成します。

# create method to determine elements contiguous to atlantis
require 'matrix'            
atlantis = [[2,3],[3,4]]
tmpl = [[-1,-1],[-1,0],[-1,1],[0,-1],[0,1],[1,-1],[1,0],[1,1]]

ln = 0
sl = []
while ln < atlantis.length
  n = 0
  tsl = []
  while n < 8
    tsl[n] = [atlantis[ln], tmpl[n]].transpose.map { |x| x.reduce(:+) }
    n = n+ 1
  end
  sl = sl + tsl
  ln = ln + 1
end
sl = sl - atlantis
sl.uniq!
sl.to_a.each { |r| puts r.inspect }

しかし、ここに示されているものよりも2レベル上のループが必要であるという問題があります(1つは設定されたサイズに達するまでアトランティスに土地を追加し続けるため、もう1つは追加の島、バミューダ、カタリナなどを作成するため) 。)そしてすでにこれは読みやすく、理解するのが難しくなっています。オブジェクト指向プログラミングについての私の漠然とした理解は、これらのループのいくつかをメソッドに変えることによって、この風邪を改善することを示唆しています。しかし、私は35年前に基本的なプログラミングを学び、Rubyをそのまま学ぶのに苦労しています。だから私の要求は:

  1. 実際、これらをメソッドに変換する方が良いでしょうか?

  2. もしそうなら、誰かが何かをメソッドに変更することによってそれがどのように行われるかを私に見せてくれるでしょうか?

  3. レベルを追加して、結果としてより低いメソッドで何かを変更する必要があることに気付いた場合、どうしますか?sl(たとえば、の1つの値だけで作成する方法の単純なケースを理解した後、atlantis戻ってそれをより長い値に作り直す必要がありました。)

このように質問することで、他のヌービーにも役立つものになることを願っています。

ところで、Stack Overflowで見つけたこのビット.transpose.map { |x| x.reduce(:+) }(何時間も試してみた後は、単純なはずで、できなかった場合は明らかな何かが欠けているはずです。ええ、あなたも知っていると思います。)要素ごとに2つの配列があり、どのように機能するのかわかりません。)

4

1 に答える 1

0

すでにこれを読んでフォローするのが難しくなっています

読みやすく従うのが難しくないようにする 1 つの方法は、コードを「自己文書化」して、読みやすい変数名と Ruby のイディオムを使用して混乱を減らすことです。

コードを簡単にリファクタリングすると、次のようになります。

require 'matrix'            
atlantis = [[2,3],[3,4]]
template = [[-1,-1],[-1,0],[-1,1],[0,-1],[0,1],[1,-1],[1,0],[1,1]]

shoreline = []
atlantis.each do |atlantum|
  shoreline += template.inject([]) do |memo, element|
    memo << [atlantum, element].transpose.map { |x| x.reduce(:+) }
    memo
  end
end

shoreline = shoreline - atlantis
shoreline.uniq!
shoreline.each { |r| puts r.inspect }

メインの処理ブロックはサイズが半分になり、(できれば) より読みやすくなりました。ここから、extract メソッドのリファクタリングを使用して、必要な場合や必要な場合はさらに整理することができます。

于 2012-07-30T07:27:00.400 に答える