找到n的最近的下一个数字,加上2个数的倍数

时间:2017-01-12 19:14:58

标签: algorithm

对于给定的数字n,找出下一个最接近的数字之间的差异,该数字可以用两个给定数字(a,b)和n的倍数形成。

Example:
    n = 49, (a, b) = (13, 17) => Difference = 2
    Nearest number would be = 51 (3*17, 0*13)

    n = 16, (a, b) = (2 , 5) => Difference = 0
    Nearest number would be = 16 (2*5, 3*2)

    n = 25, (a, b) = (13, 17) => Difference = 1
    Nearest number would be = 26 (0*17, 2*13)

我该如何解决这个问题?

我写的是:(在红宝石中)

def find_next_num_diff(x,y,z)
  x, y = x > y ? [x, y] : [y, x]
  while(z%y > 0 && z >= x) do
    z -= x
  end
  if z%y == 0
    return 0
  else
    return [y-(z%y), x-z].min
  end
end

以上代码不适用于最后一种示例。

编辑: 没有负数。只有总和。 起初我认为这个问题是求解方程的X & Y Xa + Yb >= nX, Y > 0

2 个答案:

答案 0 :(得分:1)

我会从这样的事情开始:

def find_next_num_diff(n, a, b)
  multiples_of_a = (0..n+a-1).step(a).to_a
  multiples_of_b = (0..n+b-1).step(b).to_a

  multiples_of_a.product(multiples_of_b).map { |x, y| (n - (x + y)).abs }.min
end

find_next_num_diff(49, 13, 17)
#=> 2
find_next_num_diff(16, 2, 5)
#=> 0
find_next_num_diff(25, 13, 17)
#=> 1

或者您可能希望使用以下需要较少内存的实现,因为它不会将笛卡尔积存储在内存中:

def find_next_num_diff(n, a, b)
  a_multiples = (0..n+a-1).step(a)
  b_multiples = (0..n+b-1).step(b)

  smallest = Float::INFINITY

  a_multiples.each do |x|
    b_multiples.each do |y|
      smallest = [smallest, (n - (x + y)).abs].min
    end
  end

  smallest
end

答案 1 :(得分:0)

我非常有信心这是一个非常低效的解决方案,但我相信这是有效的。它使用递归,分支因子为2:

def recurse(a_base, b_base, a_mult, b_mult, n):
    a = a_base * a_mult
    b = b_base * b_mult

    if a + b >= n:
        return (a + b) - n, a_mult, b_mult
    else:
        diff_1, a_mult_1, b_mult_1 = recurse(a_base, b_base, a_mult + 1, b_mult, n)
        diff_2, a_mult_2, b_mult_2 = recurse(a_base, b_base, a_mult, b_mult + 1, n)

        if diff_1 <= diff_2:
            return diff_1, a_mult_1, b_mult_1
        else:
            return diff_2, a_mult_2, b_mult_2


def find_next_num_diff(a, b, n):
    return recurse(a, b, 0, 0, n)


if __name__ == '__main__':
    print(find_next_num_diff(13, 17, 49))
    print(find_next_num_diff(2, 5, 16))
    print(find_next_num_diff(13, 17, 25))

<强>输出

# Smallest diff, multiple of a, multiple of b
(2, 0, 3)
(0, 8, 0)
(1, 2, 0)

为方便起见,以下是您的帖子中要比较的示例:

n = 49, (a, b) = (13, 17) => Difference = 2
Nearest number would be = 51 (3*17, 0*13)

n = 16, (a, b) = (2 , 5) => Difference = 0
Nearest number would be = 16 (2*5, 3*2)

n = 25, (a, b) = (13, 17) => Difference = 1
Nearest number would be = 26 (0*17, 2*13)

请注意,我的解决方案为第二个示例产生了不同的倍数组合,但diff仍为0。