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

一种纯函数式的方式:

def func(a, x, i = 0)
  if i == a.size - 1
    a
  else
    if a[i] <= a[i + 1] * x
      func a, x, i + 1
    else
      func a.take(i + 1) + [(a[i].to_f / x).ceil] + a.drop(i + 1), x, i + 1
    end
  end
end

我得到的输出与您的第一个和第三个示例完全相同,但不是第二个 - 您的示例输出似乎不正确。

测试:

p func [5, 3], 1.5
p func [50, 4], 1.5
p func [50, 20, 10, 4, 3, 2], 1.5

输出:

[5, 4, 3]
[50, 34, 23, 16, 11, 8, 6, 4]
[50, 34, 23, 20, 14, 10, 7, 5, 4, 3, 2]
于 2013-07-09T18:05:11.250 回答
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 回答