如何在Ruby中生成锦标赛时间表?

rwl*_*wl4 5 ruby algorithm

我一直在搜索各地,包括Stack Overflow档案,以获得如何做到这一点的答案,我尝试自己动手,但是我已经做了简短,所以我决定在这里发布我的请求.

我需要在数组中获取任意(偶数)个项目,并返回与数组中的另一个项目配对的项目.我需要代码的输出与我在下面包含的输出示例相同.

输入:

('A'..'H').to_a

输出:

[[['A','H'], ['B','G'], ['C','F'], ['D','E']],
 [['A','G'], ['B','F'], ['C','E'], ['D','H']],
 [['A','F'], ['B','E'], ['C','D'], ['G','H']],
 [['A','E'], ['B','D'], ['C','H'], ['F','G']],
 [['A','D'], ['B','C'], ['E','G'], ['F','H']],
 [['A','C'], ['B','H'], ['D','G'], ['E','F']],
 [['A','B'], ['C','G'], ['D','F'], ['E','H']]]

有任何想法吗?

这是我到目前为止所做的.它有点脏,并没有按照我需要的顺序返回.

items = ('A'..'H').to_a
combinations = []

1.upto(7) do |index|
  curitems = items.dup
  combination = []
  1.upto(items.size / 2) do |i|
    team1 = curitems.delete_at(0)
    team2 = curitems.delete_at(curitems.size - index) || curitems.delete_at(curitems.size - 1)
    combination << [team1, team2]
  end
  combinations << combination
end

pp combinations

输出接近,但顺序不正确:

[[["A", "H"], ["B", "G"], ["C", "F"], ["D", "E"]],
 [["A", "G"], ["B", "F"], ["C", "E"], ["D", "H"]],
 [["A", "F"], ["B", "E"], ["C", "D"], ["G", "H"]],
 [["A", "E"], ["B", "D"], ["C", "H"], ["F", "G"]],
 [["A", "D"], ["B", "C"], ["E", "G"], ["F", "H"]],
 [["A", "C"], ["B", "H"], ["D", "E"], ["F", "G"]],
 [["A", "B"], ["C", "G"], ["D", "H"], ["E", "F"]]]

你会注意到我的代码得到了两个D < - > H组合(最后一行和第二行),但这不起作用.

我对OP的要求[FM]的理解:

  • 给定N团队(例如,8个团队:) A..H.
  • 创建锦标赛时间表,包括R轮次游戏(在我们的示例中为7)和G游戏(在我们的示例中为28).
  • 每个团队只有一次与其他团队比赛.
  • 每支球队每轮比赛一次.
  • 而且(困难的部分)一轮中的游戏排序如下:
  • 排名第一的球队(A)首先打出排名较低的球队(H).
  • 如果候选对手因违反无重复规则而被拒绝,则将排名较低的球队置于"后烧"并首先形成其他对位.然后使用相同的规则匹配后端刻录机团队.(例如:在第2轮中,第一个候选对战A-H被拒绝作为重复,因此第1场比赛将是A-G,H并将坐在后面,与D该轮中的最后一场比赛配对).
  • 将团队添加到后台时,将它们添加到该列表的前面(即,在后端刻录机上保留等级排序).
  • 注意:第5轮是棘手的.前两场比赛很简单.第三场比赛将是E-H; 然而,这创造了第四场比赛将是重复(F-G)的场景.因此算法需要回溯,拒绝E-H配对,而是E-G在第3场比赛中进行.

Sva*_*nte 5

你似乎想要一个循环计划.原理很简单:

如果你从这个设置开始(上排的队伍对阵相应的较低队伍):

A B C D
H G F E
Run Code Online (Sandbox Code Playgroud)

您将一个团队设置为固定(例如,A)并旋转其余团队(例如,顺时针):

A H B C     A G H B     A F G H     A E F G    A D E F    A C D E  
G F E D     F E D C     E D C B     D C B H    C B H G    B H G F
Run Code Online (Sandbox Code Playgroud)

Voilà,7轮,每支球队互相比赛.

编辑:我更改了此示例中的枚举顺序以反映您的示例输出,但这只会让对手A正确.


gle*_*ald 5

好吧,我可以让你的8队示例正确,但我不知道如何概括调整.但也许这会让你思考......

games = (1...teams.size).map do |r|
  t = teams.dup
  (0...(teams.size/2)).map do |_|
    [t.shift,t.delete_at(-(r % t.size + (r >= t.size * 2 ? 1 : 0)))]
  end
end
Run Code Online (Sandbox Code Playgroud)