Ruby-“自动贩卖机”返回更改

时间:2018-08-11 16:45:20

标签: arrays ruby sum

在红宝石中,我试图制作一个简单的财务脚本来返回一组数字[i] ,这些数字代表输入的金额[n] 由用户。

我的阵列将付款“ [5.0, 1.5, 0.5, 2, 1]”的“部分”分成总金额的分期付款。

  

示例:arr = [5.0, 1.5, 0.5, 2, 1]中,总数等于10.0

如果用户输入4.5,则该方法应返回[i]作为[1.5, 2, 1]

任何人都可以帮助我建立[i]方法吗?

2 个答案:

答案 0 :(得分:0)

如果您使用的是Ruby 2.4或更高版本,则只需执行arr.sum,即可查找仅包含数字的数组的总和。

https://ruby-doc.org/core-2.4.0/Array.html#method-i-sum

答案 1 :(得分:0)

正如@pjs所说,您的问题看起来模棱两可。

如果要获取数组的总和,请使用:array.reduce(0.0, &:+)甚至是array.sum

如果您想获取一个将汇总为给定N的数组,那么您没有提供足够的详细信息。有什么限制?您不能只做类似4.5 -> [1, 1, 1, 1, 0.5]的事情吗?

upd

作者给了我们一个细节。我们有一个数组[5.0, 1.5, 0.5, 2, 1],通过给定的数字N,我们应该找到一个由该数组中等于N的数字组成的总和。基本上,这就像自动售货机的更换问题(应该给客户多少硬币)。

您可以像“自动售货机更换算法”一样在Google上对其进行搜索。例如:Java Algorithm to solve vendor machine 'change giving' problem

这是我简单的动态编程解决方案:

ALLOWED_NUMBERS = [5.0, 1.5, 0.5, 2, 1].sort.freeze

def into_sum_of_allowed_numbers(n)
  return [] if n == 0
  @cache ||= {}
  return @cache[n] if @cache[n]

  ALLOWED_NUMBERS.reverse_each do |x|
    next if n - x < 0
    lesser_sum = into_sum_of_allowed_numbers(n - x)
    next unless lesser_sum
    @cache[n] = lesser_sum + [x]
    return @cache[n]
  end
  nil
end

into_sum_of_allowed_numbers(4.5) # ==> [0.5, 2, 2]

基本上,这个想法很简单。对于允许的数字a, b, c,数字n的总和是[*sum_for(n - a), a][*sum_for(n - c), c][*sum_for(n - c), c]

您可以在没有@cache的情况下执行此操作,尽管它会慢很多。

我想有更好的解决方案,但是递归解决方案对我来说似乎最简单。