0
def peel array
  output = []

  while ! array.empty? do
    output << array.shift
    mutate! array
  end

  output.flatten
end

私は変異を含めていません!出力変数の削除のみに関心があるためです。突然変異!配列が変化しているため、 each を使用して配列を反復処理できないため、呼び出しは重要です。

編集:出力として配列を取得しています。これが必要です。array.shiftメソッドは正しく機能しますが、一時変数を使用せずに値を収集する方法があると思います。

編集 #2: OK、これが mutate です! メソッドとテストケース:

def mutate! array
  array.reverse!
end

a = (1..5).to_a
peel( a ).should == [ 1, 5, 2, 4, 3 ]

peel配列を変更しても問題ありません。と呼ぶべきだと思いますpeel!。はい、mutate!各要素が削除された後に呼び出す必要があります。

4

3 に答える 3

1

このすべての逆転は私をめまいさせます。

def peel(array)
  indices = array.size.times.map do |i|
    i = -i if i.odd?
    i = i/2
  end 
  array.values_at(*indices) # indices will be [0, -1, 1, -2, 2] in the example
end

a = (1..5).to_a
p peel(a) #=>[1, 5, 2, 4, 3]
于 2013-10-06T20:09:38.637 に答える
0

並列割り当てを使用する方法は次のとおりです。

def peel array
  n = array.size
  n.times {|i| (n-2-2*i).times {|j| array[n-1-j], array[n-2-j] = array[n-2-j], array[n-1-j]}}
  array      
end

peel [1,2,3,4,5] # => [1,5,2,4,3]
peel [1,2,3,4,5,6] # => [1,6,2,5,3,4]

ここで行っているのは、一連のペアワイズ交換です。例として、 の場合[1,2,3,4,5,6]、最初の 6-2=4 ステップ (6 は配列のサイズ) は次のように配列を変更します。

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

1、6、2 が正しい位置に配置されました。これらの手順を繰り返しますが、今回は 6-4=2 回だけで、5 と 3 を正しい位置に移動します。

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

4 が最後まで押し込まれ、正しい位置になったので終了です。

于 2013-10-06T23:00:09.820 に答える