[英]Show only the combinations of two permutated arrays that have a sum less than or equal to target number
I have two arrays: teams = [1,2,3]
and drivers = [4,5,6]
.我有两个 arrays: teams = [1,2,3]
和drivers = [4,5,6]
。 Using permutations I have managed to show all combinations of the two arrays, but have managed to define what number of values I'd like to use from each array.使用排列,我设法显示了两个 arrays 的所有组合,但设法定义了我想从每个数组中使用的值的数量。 So from 'Teams' I have used 1 value and 'Drivers' I have used two.因此,在“团队”中我使用了 1 个值,在“驱动程序”中我使用了两个。 I would like to only show the combinations where the sum is less than or equal to 10 and remove any duplicates.我只想显示总和小于或等于 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
This is successfully outputting all combinations of the two arrays using 1 number from teams and 2 from drivers as follows:这是使用 1 个来自团队的数字和 2 个来自司机的数字成功输出两个 arrays 的所有组合,如下所示:
[[1], [4, 5]], [[1], [4, 6]], [[1], [5, 4]], [[1], [5, 6]], [[1], [6, 4]], [[1], [6, 5]], [[2], [4, 5]],
etc... [[1], [4, 5]], [[1], [4, 6]], [[1], [5, 4]], [[1], [5, 6]], [[1], [6, 4]], [[1], [6, 5]], [[2], [4, 5]],
等等...
To only show values less than or equal to 10 my expected outcome would be: [[1], [4, 5]], [[1], [5, 4]],
要仅显示小于或等于 10 的值,我的预期结果将是: [[1], [4, 5]], [[1], [5, 4]],
and then no duplicates would leave me with just: [[1], [4, 5]]
然后没有重复会让我只剩下: [[1], [4, 5]]
I have tried adding the below line of code but am getting an undefined method `<=' error:我尝试添加以下代码行,但出现未定义的方法“<=”错误:
@array = array[0].product(*array[1..-1]).select { |a| a.reduce(:+) <= target }
I have also tried this with no luck:我也试过这个但没有运气:
result = array.combination(1).select{|combi| combi.sum <= target}
@array = result
I'm guessing it's something to do with the permutation?我猜这与排列有关?
teams = [1,2,3]
drivers = [2,5,4,5,6,4,5,7]
max_driver_sum = 10
I have assumed that drivers
can contain duplicate elements (as in my example), but I will explain at the end how the calculations would simplify if there are no duplicates.我假设drivers
可以包含重复元素(如我的示例),但我将在最后解释如果没有重复元素,计算将如何简化。
As a first step let's partition drivers
between values that are repeated and those that are not.作为第一步,让我们在重复值和不重复值之间划分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]]
Therefore,所以,
dup_drivers
#=> [5, 4]
uniq_drivers
#=> [2, 6, 7]
See Enumerable#tally and Enumerable#partition .请参阅Enumerable#tally和Enumerable#partition 。
Here,这里,
counts.partition { |_d,n| n > 1 }
#=> [[[5, 3], [4, 2]], [[2, 1], [6, 1], [7, 1]]]
First compute the unique combinations in which the two drivers are equal:首先计算两个驱动程序相等的唯一组合:
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]]]
Next, compute the unique combinations in which the two drivers are not equal:接下来,计算两个驱动程序不相等的唯一组合:
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]]]
SeeArray#combination .参见数组#combination 。
The final step is to combine the two groups of combinations:最后一步是组合两组组合:
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]]]
Sorted, this result is as follows.排序后,这个结果如下。
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]]]
Notice that Array#uniq was not used in the foregoing.请注意, Array#uniq没有在前面使用。 If desired, one could of course substitute out some of the variables above.如果需要,当然可以替换掉上面的一些变量。
If drivers
contains no duplicates the desired array is given by uniq_combos
where all_uniq
is replaced by drivers
in the calculation of all_uniq_combos
.如果drivers
不包含重复项,则所需数组由uniq_combos
给出,其中all_uniq
在all_uniq_combos
的计算中被drivers
替换。 If, for example,例如,如果
teams = [1,2,3]
drivers = [2,5,4,6,7]
max_driver_sum = 10
then然后
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]]]
Here's an approach这是一种方法
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]]]
Getting the unique items (modified to also work for values of teams > drivers)获得独特的物品(修改后也适用于团队>车手的价值)
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.