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



我有两个数组:teams = [1,2,3]drivers = [4,5,6]。通过排列,我成功地显示了这两个数组的所有组合,但也成功地定义了我希望从每个数组中使用的值的数量。所以我在"车队"中使用了1个值,在"车手"中使用了2个值。我只想显示总和小于或等于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个来自车手,如下所示:

[[1], [4, 5]], [[1], [4, 6]], [[1], [5, 4]], [[1], [5, 6]], [[1], [6, 4]], [[1], [6, 5]], [[2], [4, 5]],etc…

仅显示小于或等于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]]]

看到数组#组合。


最后一步是合并两组组合:

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]]]

获取唯一项(修改后也适用于teams>驱动程序)

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]]]

相关内容

  • 没有找到相关文章

最新更新