3

整数の配列を降順で変換する関数が必要です。位置 i の整数が位置 i+1 の整数よりも X 倍大きくならないようにし、その間に 1 つ以上の要素を追加し、元の数値をそのまま維持します。 .

結果の並べ替えられた配列は、次の基準を満たします。

array[i] <= array[i+1]*1.5 

すべての i について。

例:

x = 1.5

上の変換

a = [5, 3]
func(a, x) = [5,4,3]

a[0] > a[1]*1.5, so func adds 4 = (a[0].to_f/1.5).ceil and sorts a
a is now [5,4,3]

b 上の変換

b = [50, 4]
func(b, x) = [50, 34, 23, 16, 11, 8, 6, 4]

b[0] > b[1]*1.5, so func adds 34 = (b[0].to_f/1.5).ceil and sorts b
b is now [50,34,4]

b[1] > b[2]*1.5, so func adds 23 = (b[1].to_f/1.5).ceil and sorts b
b is now [50,34,23,4]

b[2] > b[3]*1.5, so func adds 16 = (b[2].to_f/1.5).ceil and sorts b
b is now [50,34,23,16,4]

b[3] > b[4]*1.5, so func adds 11 = (b[3].to_f/1.5).ceil and sorts b
b is now [50,34,23,16,11,4]

b[4] > b[5]*1.5, so func adds 8 = (b[4].to_f/1.5).ceil and sorts b
b is now [50,34,23,16,11,8,4]

b[5] > b[6]*1.5, so func adds 6 = (b[5].to_f/1.5).ceil and sorts b
b is now [50,34,23,16,11,8,4]

func returns [50, 34, 23, 16, 11, 8, 6, 4]

c 上の変換

c = [50, 20, 10, 4, 3, 2]
func(c, x) = [50, 34, 23, 20, 14, 10, 7, 5, 4, 3, 2]

c[0] > c[1]*1.5, so func adds 34 = (c[0].to_f/1.5).ceil and sorts c
c is now [50,34,20,10,4,3,2]

c[1] > c[2]*1.5, so func adds 23 = (c[1].to_f/1.5).ceil and sorts c
c is now [50,34,23,20,10,4,3,2]

c[3] > c[4]*1.5, so func adds 14 = (c[3].to_f/1.5).ceil and sorts c
c is now [50,34,23,20,14,10,4,3,2]

c[5] > c[6]*1.5, so func adds 7 = (c[5].to_f/1.5).ceil and sorts c
c is now [50,34,23,20,14,10,7,4,3,2]

c[6] > c[7]*1.5, so func adds 5 = (c[6].to_f/1.5).ceil and sorts c
c is now [50,34,23,20,14,10,7,5,4,3,2]

func returns [50, 34, 23, 20, 14, 10, 7, 5, 4, 3, 2]

これを機能的かつクリーンな方法で行うにはどうすればよいでしょうか?

4

2 に答える 2

1

これは役に立つかもしれません。間隔を幾何学的に分割して、最後のものを除くすべてに 1.5 を使用し、残りをすべて使用するのではなく、各サブディビジョンが (できるだけ近い) 他のものと同じ乗数を持つようにします。

include Math

def geometric_interpolation(arr, ratio)

  log_ratio = log(ratio)
  result = []

  arr.each_cons(2) do |pair|
    logs = pair.map { |x| log(x) }
    log_interval = logs[0] - logs[1]
    num = (log_interval / log_ratio).round(12).ceil
    result += [ pair[0] ] + (1...num).map { |n| exp(logs[0] - log_interval * n / num).round }
  end

  result + [ arr[-1] ]

end

a = [5, 3]
b = [50, 4]
c = [50, 20, 10, 4, 3, 2]

p geometric_interpolation(a, 1.5)
p geometric_interpolation(b, 1.5)
p geometric_interpolation(c, 1.5)

出力

[5, 4, 3]
[50, 35, 24, 17, 12, 8, 6, 4]
[50, 37, 27, 20, 14, 10, 7, 5, 4, 3, 2]
于 2013-07-09T18:50:46.330 に答える