数组中元素的随机总和等于y - ruby

时间:2016-03-17 07:11:31

标签: ruby-on-rails ruby ruby-on-rails-4

需要创建一个总和应该等于预期值的数组。

 inp = [1,2,3,4,5,6,7,8,9,10]
 sum = 200

输出:

out = [10,10,9,1,3,3,3,7,.....]  whose sum should be 200
or
out = [10,7,3,....]              Repeated values can be used
or
out = [2,3,4,9,2,....]

我试过,

arr = [5,10,15,20,30]
ee = []
max = 200
while (ee.sum < max) do
  ee << arr.sample(1).first
end

ee.pop(2)
val = max - ee.sum
pair = arr.uniq.combination(2).detect { |a, b| a + b == val }
ee << pair
ee.flatten

有没有有效的方法呢。

2 个答案:

答案 0 :(得分:2)

inp = [1,2,3,4,5,6,7,8,9,10]
sum = 20

inp.length.downto(1).flat_map do |i|
  inp.combination(i).to_a # take all subarrays of length `i`
end.select do |a| 
  a.inject(:+) == sum     # select only those summing to `sum`
end

有人可能会得到结果数组的random元素。

result = inp.length.downto(1).flat_map do |i|
  inp.combination(i).to_a # take all subarrays of length `i`
end.select do |a| 
  a.inject(:+) == sum     # select only those summing to `sum`
end
puts result.length
#⇒ 31
puts result.sample
#⇒ [2, 4, 5, 9]
puts result.sample
#⇒ [1, 2, 3, 6, 8]
...

请注意,这种方法对于长距离输入效率不高。同样,如果任何原始数组的成员可能被多次使用,则上面的combination应更改为permutation,但此解决方案效果太差,无法与permutation一起使用。

答案 1 :(得分:0)

我在以下链接中找到了这个问题的答案:

Finding all possible combinations of numbers to reach a given sum

def subset_sum(numbers, target, partial=[])
 s = partial.inject 0, :+
 #check if the partial sum is equals to target
 puts "sum(#{partial})=#{target}" if s == target
 return if s >= target  #if we reach the number why bother to continue
 (0..(numbers.length - 1)).each do |i|
   n = numbers[i]
   remaining = numbers.drop(i+1)
   subset_sum(remaining, target, partial + [n])
 end
end

subset_sum([1,2,3,4,5,6,7,8,9,10],20)