2017-10-14 10 views
0

あなたがどのようにして、ループが無制限にネストされたループを作成しますか?

list = (0..9999).to_a 

idx = 0 

while idx < list.length 
    idx2 = idx 
    while idx2 < list.length 
    puts list[idx] + list[idx2] if (list[idx] + list[idx2]).odd? 
    idx2 += 1 
    end 
    idx += 1 
end 

のようなものを記述して使用すると、2つの要素を比較するために必要な場合でも、比較の数は何である場合は、リスト[1、2、3 ...... n]は を持っていると言います定数ではなく、増加しますか? このコードは、別のループ内に1つのループを持つことによって比較をハードコードしていますが、4つ以上の要素を比較する必要がある場合は、最大数の比較を知らない場合にどのようにループを作成しますか?

答えて

2

我々はこれを行うにはルビーに役立つ方法を持って、それはArray#combination次のとおりです。

def find_odd_sums(list, num_per_group) 
    list.combination(num_per_group).to_a.map(&:sum).select(&:odd?) 
end 

あなたが選択した場合は、combination再実装することができます。この機能の多くのバージョンが利用可能ですAlgorithm to return all combinations of k elements from n

+1

'Array#combination'の後に' Enumerator#to_a'を削除することができます。 6文字未満だから削除できません。 –

0

この質問は不明です。第1に、漠然としているタイトルは、無言の問題に対する特定のアプローチをどのように実施できるかを尋ねる。最初に必要なのは、問題の言葉での声明です。

私はその声明が何であるかを推測し、解決策を提案します。

考える

  • 配列arr
  • 正の整数n,1 <= n <= arr.size;そして
  • trueを返すために、どのようなarr原因mn要素の組み合わせtrueまたはfalseを返すarrの明確な要素ですn引数、

を有する方法m

メソッドmの定義と組み合わせて、以下のメソッドを使用することができます。

def combos(arr, n, m) 
    arr.combination(n).select { |x| public_send(m, *x) } 
end 

もちろん、キーはメソッドArray#combinationです。メソッドEnumerable#selectObject#public_sendのドキュメントを参照してください。

ここでは、質問に記載されている例を使用しています。

def m(*x) 
    x.sum.odd? 
end 

arr = [1,2,3,4,5,6] 

combos(arr, 2, :m) 
    #=> [[1, 2], [1, 4], [1, 6], [2, 3], [2, 5], [3, 4], [3, 6], [4, 5], [5, 6]] 
combos(arr, 3, :m) 
    #=> [[1, 2, 4], [1, 2, 6], [1, 3, 5], [1, 4, 6], [2, 3, 4], [2, 3, 6], 
    # [2, 4, 5], [2, 5, 6], [3, 4, 6], [4, 5, 6]] 
combos(arr, 4, :m) 
    #=> [[1, 2, 3, 5], [1, 2, 4, 6], [1, 3, 4, 5], [1, 3, 5, 6], [2, 3, 4, 6], [2, 4, 5, 6]] 

それはRubyのV2.4でデビューだ作られている(Array#sumのためのドキュメントを参照してください

ここで第二の例です:5つの文字の組み合わせは、2つの母音を持つ文字の配列、与えられた

VOWEL_COUNTER = %w| a e i o u |.product([1]).to_h.tap { |h| h.default=0 } 
    #=> {"a"=>1, "e"=>1, "i"=>1, "o"=>1, "u"=>1} 
VOWEL_COUNTER['a'] 
    #=> 1 

ハッシュのデフォルト値をゼロに設定すると、VOWEL_COUNTER[k]は、キーがkでない場合はゼロを返します。例えば、以下のように

VOWEL_COUNTER['r'] 
    #=> 0 

def m(*x) 
    x.sum { |c| VOWEL_COUNTER[c] } == 2 
end 

arr = %w| a r t u e v s |  
combos(arr, 5, :m) 
    #=> [["a", "r", "t", "u", "v"], ["a", "r", "t", "u", "s"], 
    # ["a", "r", "t", "e", "v"], ["a", "r", "t", "e", "s"], 
    # ["a", "r", "u", "v", "s"], ["a", "r", "e", "v", "s"], 
    # ["a", "t", "u", "v", "s"], ["a", "t", "e", "v", "s"], 
    # ["r", "t", "u", "e", "v"], ["r", "t", "u", "e", "s"], 
    # ["r", "u", "e", "v", "s"], ["t", "u", "e", "v", "s"]] 

なおVOWEL_COUNTERが構成されています。このハッシュで

a = %w| a e i o u | 
    #=> ["a", "e", "i", "o", "u"] 
b = a.product([1]) 
    #=> [["a", 1], ["e", 1], ["i", 1], ["o", 1], ["u", 1]] 
c = b.to_h 
    #=> {"a"=>1, "e"=>1, "i"=>1, "o"=>1, "u"=>1} 

c['r'] 
    #=> nil 

ので、我々はゼロにデフォルト値を設定する必要があります。 NilClass#to_iがゼロにnilを変換

x.sum { |c| VOWEL_COUNTER[c].to_i } == 2 

ので

VOWEL_COUNTER = c.tap { |h| h.default=0 } 
    #=> {"a"=>1, "e"=>1, "i"=>1, "o"=>1, "u"=>1} 
c['r'] 
    #=> 0 

代わりに、我々は最後のステップ(ゼロにハッシュのデフォルトの設定)を省略し、書かれている可能性があります。

は、メソッドの#selectのためにも、ドキュメントを参照してください、#public_send

0

は、私は誰もがそれがあるよりも、このより複雑になっているように感じます。あなたは確かに正しい方向(Array#combinationArray#repeated_combinationArray#permutationArray#repeated_permutation)を指しています。あなたがやっている正確なことを実現するためには、単に行うことができます。

list.repeated_combination(2) { |c| puts c.sum if c.sum.odd? } 

それらの間の違いを見るために上記のリンクをチェックしてください。

あなたができるヘルパーメソッドを作成したい場合は、私の意見では、この場合は本当に必要ではありません。 2を探している番号に置き換えてください。

関連する問題