4

1 から 40 までの可変長の ruby​​ に複数の配列があります。

@items は、長さが 1 ~ 40 の典型的な配列です。例えば

@items = [1, 2, 3, 4, 5, 6]

配列を長さ1、2、または3の小さな配列にランダムに分割して、(たとえば)の結果を得たい

@items = [[1, 2],[3],[4,5,6]]

また

@items = [[1],[2, 3],[4],[5,6]]

@items.each_slice(3)... を使用して配列を分割できることはわかっています。ここで、3 は固定長です。しかし、可変長の大きな配列をランダムに1、2、または3の配列サイズにランダムに分割したい...これを達成する最良の方法は何ですか?

4

5 に答える 5

7
items, @items = @items.dup, []
@items.push(items.shift(rand(1..3))) until items.empty?
于 2013-03-20T00:40:12.940 に答える
3
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
b = []
until a.empty?
  b << a.shift((1..a.size).to_a.sample)
end
# b => [[1, 2], [3, 4, 5, 6, 7], [8, 9], [10]]
# change everytime though

a.sizeをまたは必要なものに置き換えることで、サブ配列のサイズを制限でき3ます。

于 2013-03-20T00:38:56.083 に答える
1

この解決策では、ローカル変数が多すぎる可能性がありますが、入力配列を破壊せず、配列ウィンドウの最大値に柔軟に対応できます。

def rotateAndTake inputArray, windowSize
  rotator, returnArray, breaker = 0, [], true
  while breaker do
    window = rand(windowSize)+1
    if(rotator + window > inputArray.length) then
      window = inputArray.length - rotator
      breaker = false
    end
    returnArray << inputArray.rotate(rotator).take(window) if window > 0
    rotator += window
  end
  returnArray
end

また、「回転」メソッドを使用したソリューションを書きたかっただけです。

于 2013-03-21T02:27:08.727 に答える
1

残念ながら、この問題の変更方法のない純粋な関数型を試してみようと思いました。

( (0..@items.size)
    .inject([0]) { |m,_| m + [m.last + 1 + rand(3)] }
    .take_while  { |i| i < @items.size } + [@items.size] ).
  each_cons(2).
  map { |s,e| @items[s...e] }
于 2013-03-20T01:37:17.007 に答える
0

別の機能的なソリューションは次のとおりです。

( [0]+
  (1..a.length-1)
    .to_a
    .sample(rand(a.length))
    .sort+
  [a.length]
).each_cons(2).map{|i,j| a[i..j-1]}
于 2013-03-20T07:16:34.670 に答える