[英]Split an array of numbers to arrays whose sum is less or equal than a given number
[英]Show only the combinations of two permutated arrays that have a sum less than or equal to target number
我有两个 arrays: teams = [1,2,3]
和drivers = [4,5,6]
。 使用排列,我设法显示了两个 arrays 的所有组合,但设法定义了我想从每个数组中使用的值的数量。 因此,在“团队”中我使用了 1 个值,在“驱动程序”中我使用了两个。 我只想显示总和小于或等于 10 的组合,并删除所有重复项。
teams = [1,2,3]
drivers = [4,5,6]
team = teams.permutation(1).to_a
driver = drivers.permutation(2).to_a
array = team.product(driver)
target = 11
这是使用 1 个来自团队的数字和 2 个来自司机的数字成功输出两个 arrays 的所有组合,如下所示:
[[1], [4, 5]], [[1], [4, 6]], [[1], [5, 4]], [[1], [5, 6]], [[1], [6, 4]], [[1], [6, 5]], [[2], [4, 5]],
等等...
要仅显示小于或等于 10 的值,我的预期结果将是: [[1], [4, 5]], [[1], [5, 4]],
然后没有重复会让我只剩下: [[1], [4, 5]]
我尝试添加以下代码行,但出现未定义的方法“<=”错误:
@array = array[0].product(*array[1..-1]).select { |a| a.reduce(:+) <= target }
我也试过这个但没有运气:
result = array.combination(1).select{|combi| combi.sum <= target}
@array = result
我猜这与排列有关?
teams = [1,2,3]
drivers = [2,5,4,5,6,4,5,7]
max_driver_sum = 10
我假设drivers
可以包含重复元素(如我的示例),但我将在最后解释如果没有重复元素,计算将如何简化。
作为第一步,让我们在重复值和不重复值之间划分drivers
。
counts = drivers.tally
#=> {2=>1, 5=>3, 4=>2, 6=>1, 7=>1}
dup_drivers, uniq_drivers = counts.partition { |_d,n| n > 1 }
.map { |arr| arr.map(&:first) }
#=> [[5, 4], [2, 6, 7]]
所以,
dup_drivers
#=> [5, 4]
uniq_drivers
#=> [2, 6, 7]
请参阅Enumerable#tally和Enumerable#partition 。
这里,
counts.partition { |_d,n| n > 1 }
#=> [[[5, 3], [4, 2]], [[2, 1], [6, 1], [7, 1]]]
首先计算两个驱动程序相等的唯一组合:
dup_combos = teams.each_with_object([]) do |t,arr|
max_driver = (max_driver_sum - t)/2
dup_drivers.each do |d|
arr << [[t],[d,d]] if d <= max_driver
end
end
#=> [[[1], [4, 4]], [[2], [4, 4]]]
接下来,计算两个驱动程序不相等的唯一组合:
all_uniq = uniq_drivers + dup_drivers
#=> [2, 6, 7, 5, 4]
all_uniq_combos = all_uniq.combination(2).to_a
#=> [[2, 6], [2, 7], [2, 5], [2, 4], [6, 7], [6, 5],
# [6, 4], [7, 5], [7, 4], [5, 4]]
uniq_combos = teams.each_with_object([]) do |t,arr|
adj_driver_sum = max_driver_sum - t
all_uniq_combos.each do |combo|
arr << [[t],combo] if combo.sum <= adj_driver_sum
end
end
#=> [[[1], [2, 6]], [[1], [2, 7]], [[1], [2, 5]], [[1], [2, 4]],
# [[1], [5, 4]], [[2], [2, 6]], [[2], [2, 5]], [[2], [2, 4]],
# [[3], [2, 5]], [[3], [2, 4]]]
参见数组#combination 。
最后一步是组合两组组合:
a1 = dup_combos + uniq_combos
#=> [[[1], [4, 4]], [[2], [4, 4]], [[1], [2, 6]], [[1], [2, 7]],
# [[1], [2, 5]], [[1], [2, 4]], [[1], [5, 4]], [[2], [2, 6]],
# [[2], [2, 5]], [[2], [2, 4]], [[3], [2, 5]], [[3], [2, 4]]]
排序后,这个结果如下。
a1.sort
#=> [[[1], [2, 4]], [[1], [2, 5]], [[1], [2, 6]], [[1], [2, 7]],
# [[1], [4, 4]], [[1], [5, 4]],
# [[2], [2, 4]], [[2], [2, 5]], [[2], [2, 6]], [[2], [4, 4]],
# [[3], [2, 4]], [[3], [2, 5]]]
请注意, Array#uniq没有在前面使用。 如果需要,当然可以替换掉上面的一些变量。
如果drivers
不包含重复项,则所需数组由uniq_combos
给出,其中all_uniq
在all_uniq_combos
的计算中被drivers
替换。 例如,如果
teams = [1,2,3]
drivers = [2,5,4,6,7]
max_driver_sum = 10
然后
all_uniq_combos = drivers.combination(2).to_a
#=> [[2, 5], [2, 4], [2, 6], [2, 7], [5, 4], [5, 6],
# [5, 7], [4, 6], [4, 7], [6, 7]]
combos = teams.each_with_object([]) do |t,arr|
adj_driver_sum = max_driver_sum - t
all_uniq_combos.each do |combo|
arr << [[t],combo] if combo.sum <= adj_driver_sum
end
end
#=> [[[1], [2, 5]], [[1], [2, 4]], [[1], [2, 6]], [[1], [2, 7]],
# [[1], [5, 4]], [[2], [2, 5]], [[2], [2, 4]], [[2], [2, 6]],
# [[3], [2, 5]], [[3], [2, 4]]]
combos.sort
#=> [[[1], [2, 4]], [[1], [2, 5]], [[1], [2, 6]], [[1], [2, 7]],
# [[1], [5, 4]],
# [[2], [2, 4]], [[2], [2, 5]], [[2], [2, 6]],
# [[3], [2, 4]], [[3], [2, 5]]]
这是一种方法
teams = [1, 2, 3]
drivers = [2, 6, 5, 4]
team = teams.permutation(1).to_a
driver = drivers.permutation(2).to_a
array = team.product(driver)
target = 10
res = array.select {|i| i.map(&:sum).sum <= target}.compact
==> [[[1], [2, 6]], [[1], [2, 5]], [[1], [2, 4]], [[1], [6, 2]],
[[1], [5, 2]], [[1], [5, 4]], [[1], [4, 2]], [[1], [4, 5]],
[[2], [2, 6]], [[2], [2, 5]], [[2], [2, 4]], [[2], [6, 2]],
[[2], [5, 2]], [[2], [4, 2]], [[3], [2, 5]], [[3], [2, 4]],
[[3], [5, 2]], [[3], [4, 2]]]
获得独特的物品(修改后也适用于团队>车手的价值)
t1 = res.map {|i| i[0]}
d2 = res.map {|i| i[1].flatten.sort}
t1.zip(d2).uniq
==> [[[1], [2, 6]], [[1], [2, 5]], [[1], [2, 4]], [[1], [4, 5]],
[[2], [2, 6]], [[2], [2, 5]], [[2], [2, 4]], [[3], [2, 5]],
[[3], [2, 4]]]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.