シェルソート

単純挿入ソートの発展版。
整列されていればされているほど高速になるため、
部分的に単純挿入ソートを繰り返すことで性能を向上させる。

クイックソート登場前は最速のソートだったらしい。

#rubyでループをうまく書けず簡潔でないコードになっている
#挿入を行う条件は2つ
#	1:先頭まで挿入位置が見つからない場合	=> 先頭に挿入
#	2:先頭まで確認する前に挿入位置が見つかった場合 => 途中に挿入

def shellsort!(array)
  #hの最大値を求める
  #同じ集合に対してソートを繰りかえさないために
  #h=...,121,40,13,4,1となるのが好ましい
  h = 1
  while h < array.size / 9 do
     h = h * 3 + 1
  end

  while h > 0 do
    #h>0の間繰り返す
    h.step(array.size - 1, 1) do |i|
      #開始位置をhから末尾とするシェルソートを繰り返す
      target = array[i]
      insertion = nil
      (i - h).step(0, -h) do |j|
        #先頭まで繰り返す
        #挿入位置が見つかるまで要素をずらす
        insertion = j
        if array[j] < target then
          #条件2
          #挿入対象が現在位置の要素よりも大きい時
          #挿入位置が現在位置+hに決定する
          insertion += h
          break
        end
        #現在位置の要素をh右(後ろ)へずらす
        array[j + h] = array[j]
      end
      #挿入対象を挿入
      array[insertion] = target
    end
    #hを小さくする(ソートの間隔を短くしていく)
    h /= 3
  end
end

data = Array.new
while input = $stdin.gets.to_i
  break if input < 0
  data << input
end

p data
shellsort!(data)
p data