简体   繁体   English

仅显示总和小于或等于目标数的两个排列 arrays 的组合

[英]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#tallyEnumerable#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_uniqall_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.

相关问题 将数字数组拆分为总和小于或等于给定数字的数组 - Split an array of numbers to arrays whose sum is less or equal than a given number 计算数组中两个元素小于或等于总和的次数-Javascript - Count number of times two elements in array are less than or equal to a sum value - Javascript 查找满足条件的两个 arrays 之间的和组合数 - Finding the number of sum combinations between two arrays that satisfy a condition 两个排序数组,两个元素之和等于一定数目 - Two Sorted Arrays, sum of 2 elements equal a certain number 如何找到总和等于或小于给定数量的元组数? - How to find number of tuples whose sum is equal or less than a given number? 从总和小于m且大于r的n个数组中返回所有可能的排列和数字组合 - Return all possible permutations and combinations of numbers from n arrays whose sum is less than m and greater than r 返回两个不同的 arrays 中的两个元素相差 2 或更少但不相等的次数的计数 - Return the count of the number of times that the two elements in two different arrays differ by 2 or less, but are not equal 总和小于给定总和的最大子集 - Largest Subset whose sum is less than equal to a given sum Java - 在排序数组中查找总和小于数字的三个数字的所有组合 - Java - find all combinations of three numbers in sorted array that have a sum smaller than a number 找到等于输入的两个 arrays 元素之和 - finding the sum of two arrays elements that is equal to the input
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM