2016-05-10 6 views
0

配列は、1,2、および0で構成されます。私は配列内の最大反復と開始インデックスを特定しようとしています。配列内の連続する繰り返し要素のインデックスとサイズの検索

例:

2 2 1 0 2 2 2 0 1 1 

方法は、我々が上記アレイ上にこれらの入力を実証する場合、出力は次のようになり番号1又は2

のいずれかの整数arguementを、受け入れるべき

find_duplicates(2) 
=> 3,4 

find_duplicates(1) 
=> 2,8 

ここで、最初の数字は複製のサイズを示し、2番目の数字は複製の開始インデックスです。

私は配列をループして、arr[i+1]またはarr[-1]と比較しようとしましたが、これは正しい方法ではありません。どんな助けでも大歓迎です。

編集: 私は私が質問を一度にしようとしたものを貼り付けていなかった、これは私が私が続き、途中でいくつかの自信を感じることができた場合、私はどうなるものではありません。

def find_status(arr,participant) 
    status = Array.new 
#arr is a two dimensional array 
for i in 0...arr.length do 
    current_line=arr[i] 
    cons=0 
    for j in 0...current_line.length do 
     #I worked on lots of if/else/case statements here, this is just one of them 
     if current_line[j] == participant 
      cons+=1 #count consecutive 
      if current_line[j]!=participant 
       cons=0 
      end 
     end 
     status[i] = cons 
    end 
end 
return status 
end 
+0

"このメソッドは引数(1または2)を受け入れ、以下のように応答する必要があります(入力は2です):"という意味が明確ではありません。 " – sawa

+0

編集していただきありがとうございます。これは、「このメソッドは、2つの整数の1つを入力として受け取る必要があります:「1」または「2」と記述してください) – devwanderer

+0

Hello @TobySpeight申し訳ありません、それは私の悪いことでした。私は問題を解決するために有用なルビーメソッドの知識が不足しているようだ。(特に「チャンク」) – devwanderer

答えて

3
target = 2については
def max_run(arr, target) 
    _,b = arr.each_with_index. 
      chunk { |n,_| n==target }. 
      select { |tf,_| tf==true }. 
      max_by { |_,a| a.size } 
    b ? [b.size, b.first.last] : nil 
end 

arr = [1,1,2,2,2,3,1,1,1,1,2,2,2,2,3,3] 

max_run(arr,1) #=> [4, 6] 
max_run(arr,2) #=> [4, 10] 
max_run(arr,3) #=> [2, 14] 
max_run(arr,4) #=> nil 

次のように、手順は次のとおりです。

enum0 = arr.each_with_index 
    #=> #<Enumerator: [1, 1, 2, 2, 2, 3, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3] 
    # :each_with_index> 

私たちは、このenumeraによって生成される要素を見ることができます配列に変換することによりTOR:

enum0.to_a 
    #=> [[1, 0], [1, 1], [2, 2], [2, 3], [2, 4], [3, 5], [1, 6], [1, 7], [1, 8], 
    #  [1, 9], [2, 10], [2, 11], [2, 12], [2, 13], [3, 14], [3, 15]] 

継続、

enum1 = enum0.chunk { |n,_| n==target } 
    #=> #<Enumerator: #<Enumerator::Generator:0x007f9beb9b0850>:each> 

は慎重にここで戻り値を調べます。 enum1を "複合列挙子"と考えることができます。それはO(N)あるので、以下のソリューションは、おそらく最も効率的である

enum1.to_a 
    #=> [[false, [[1, 0], [1, 1]]], [true, [[2, 2], [2, 3], [2, 4]]], 
    # [false, [[3, 5], [1, 6], [1, 7], [1, 8], [1, 9]]], 
    # [true, [[2, 10], [2, 11], [2, 12], [2, 13]]], [false, [[3, 14], [3, 15]]]] 

継続、

c = enum1.select { |tf,_| tf==true } 
    #=> [[true, [[2, 2], [2, 3], [2, 4]]], 
    # [true, [[2, 10], [2, 11], [2, 12], [2, 13]]]] 
_,b = c.max_by { |_,a| a.size } 
    #=> [true, [[2, 10], [2, 11], [2, 12], [2, 13]]] 
b #=> [[2, 10], [2, 11], [2, 12], [2, 13]] 
b ? [b.size, b.first.last] : nil 
    #=> [[2, 10], [2, 11], [2, 12], [2, 13]] ? [4, [2,10].last] 
    #=> [4, 10] 
+0

詳細とよく記述されたレスポンス@Caryありがとう、以前は一度も取り組まなかった部分がありますが、私はそれを掘り下げていきます。 – devwanderer

2
a = [2, 2, 1, 0, 2, 2, 2, 0, 1, 1] 

longest_sequence = 
a.each_index.select{|i| a[i] == 2}.chunk_while{|i, j| i.next == j}.max_by(&:length) 
# => [4, 5, 6] 

[longest_sequence.length, longest_sequence.first] # => [3, 4] 
+0

非常に巧妙な答え、構成された配列は、所望の出現のインデックスで構成されています。理解しやすい – devwanderer

1

:それは次の値を生成します。それは配列を通してチャンクを集めます:

arr.each.with_index.reduce({idx:-1, i: -1, len: 0}) do |memo, (e, i)| 
    memo[:i] = i if memo[:i] == -1 && e == 2  # at the beginning of chunk 
    memo[:len], memo[:idx] = [i - memo[:i], memo[:i]] \ 
    if memo[:i] >= 0 && i - memo[:i] > memo[:len] # save values if needed 
    memo[:i] = -1 unless e == 2      # reset index counter 
    memo 
end.reject { |k, _| k == :i }      # reject temporary index value 

#⇒ { 
# :idx => 4, 
# :len => 3 
# } 

これをメソッドとして使用するには、パラメータを受け入れます。上のコードをdef find_duplicates numberと置き換え、2を上記のコードの番号に置き換えてください。はい、配列の代わりにハッシュを返します。

関連する問題