【发布时间】:2016-06-21 10:58:37
【问题描述】:
在 Ruby 上使用 combination 方法,
[1, 2, 3, 4, 5, 6].combination(2).to_a
#=> [[1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [2, 3],
# [2, 4], [2, 5], [2, 6], [3, 4], [3, 5], [3, 6],
# [4, 5], [4, 6], [5, 6]]
我们可以得到一个包含 15 (6C2) 个元素的二维数组。
我想创建一个fair_combination 方法,它返回如下数组:
arr = [[1, 2], [3, 5], [4, 6],
[3, 4], [5, 1], [6, 2],
[5, 6], [1, 3], [2, 4],
[2, 3], [4, 5], [6, 1],
[1, 4], [2, 5], [3, 6]]
这样每三个子数组(6 个的一半)包含所有给定的元素:
arr.each_slice(3).map { |a| a.flatten.sort }
#=> [[1, 2, 3, 4, 5, 6],
# [1, 2, 3, 4, 5, 6],
# [1, 2, 3, 4, 5, 6],
# [1, 2, 3, 4, 5, 6],
# [1, 2, 3, 4, 5, 6]]
这使得它有点“公平”,随着数组的继续使用尽可能不同的元素。
为了更通用,它需要满足如下:
(1) 当你从头开始跟踪数组并计算每个数字出现的次数时,在任何时候它都应该尽可能平坦;
(1..7).to_a.fair_combination(3)
#=> [[1, 2, 3], [4, 5, 6], [7, 1, 4], [2, 5, 3], [6, 7, 2], ...]
前 7 个数字组成 [1,2,...,7],接下来的 7 个数字也是如此。
(2) 一旦数字 A 与 B 在同一个数组中,如果可能,A 不希望与 B 在同一个数组中。
(1..10).to_a.fair_combination(4)
#=> [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 1, 5], [2, 6, 9, 3], [4, 7, 10, 8], ...]
有没有什么好的算法可以创建这样的“公平组合”?
【问题讨论】:
-
我讨厌成为那种人,但你有什么尝试过?
-
@NickZuber 感谢您的评论。设法创建了一种等效的 fair_combination(2); gist.github.com/honake/b685811d7644c563cd26a620274a75e6 但效果不太好,无法使其更通用。
标签: ruby algorithm math combinations