我想根据球员的排名将他们分成各个公平的团队。例如,我有一个这样的球员名单:
players = [{
name: "Qasim",
rating: 1
}, {
name: "Mahsam",
rating: 7
}, {
name: "Aj",
rating: 3
}, {
name: "Osman",
rating: 6
}, {
name: "Usama",
rating: 2
}, {
name: "Bilal",
rating: 8
}, {
name: "Kaka",
rating: 20
}, {
name: "Owen",
rating: 15
}
]
我想将他们分为4个小组,这些小组的平均总成绩最好,并且在这样的成员中也一样:
Team A Team B Team C Team D
======= ======= ======= =======
Kaka: 20 Owen: 15 Bilal: 8 Mahsam: 7
Qasim: 1 Usama: 2 Aj: 3 Osman: 6
我找到了解决此问题的方法,但是很难将其转换为ruby代码。假设我们可以拥有8个以上的玩家,并且团队数量可以从2到4个团队变化。
1. Sort all players by their ratings descendingly.
2. Assign team A the best player.
3. Assign team B the next best player.
4. Assign team C the next best player.
5. Assign team D the next best player.
6. Assign team D the next best player.
7. Assign team C the next best player.
8. Assign team B the next best player.
9. Assign team A the next best player.
10. Go to 2
11. End when we're out of players.
有人可以帮忙吗?谢谢你。
注意:实际上,该团队可以从2到4个团队变化,每个团队中的所有玩家必须相等,并且每个团队的总评分必须相等或尽可能接近相等。
玩家可以是任何数字,并且必须被团队整除。
EX:如果有2支队伍,则总人数必须为偶数。如果3支球队,则总人数必须被3除;如果4支球队,则总人数必须被4除。欢迎任何类型的答案:)
答案 0 :(得分:3)
您可以实现如下所述的分配算法。
def assign(nbr_teams, players)
flip = [true, false].cycle
players.
sort_by { |p| p[:rating] }.
each_slice(nbr_teams).
map { |a| flip.next ? a.reverse : a }.
transpose
end
assign(4, players)
#=> [[{:name=>"Osman", :rating=>6}, {:name=>"Mahsam", :rating=>7}],
# [{:name=>"Aj", :rating=>3}, {:name=>"Bilal", :rating=>8}],
# [{:name=>"Usama", :rating=>2}, {:name=>"Owen", :rating=>15}],
# [{:name=>"Qasim", :rating=>1}, {:name=>"Kaka", :rating=>20}]]
如果有2个团队,任务将如下。
assign(2, players)
#=> [[{:name=>"Usama", :rating=>2}, {:name=>"Aj", :rating=>3},
# {:name=>"Bilal", :rating=>8}, {:name=>"Owen", :rating=>15}],
# [{:name=>"Qasim", :rating=>1}, {:name=>"Osman", :rating=>6},
# {:name=>"Mahsam", :rating=>7}, {:name=>"Kaka", :rating=>20}]]
步骤如下。
nbr_teams = 4
flip = [true, false].cycle
#=> #<Enumerator: [true, false]:cycle>
Array#cycle的工作方式如下:flip.next #=> true
,flip.next #=> false
,flip.next #=> true
,依此类推。继续
a = players.sort_by { |p| p[:rating] }
#=> [{:name=>"Qasim", :rating=>1}, {:name=>"Usama", :rating=>2},
# {:name=>"Aj", :rating=>3}, {:name=>"Osman", :rating=>6},
# {:name=>"Mahsam", :rating=>7}, {:name=>"Bilal", :rating=>8},
# {:name=>"Owen", :rating=>15}, {:name=>"Kaka", :rating=>20}]
b = a.each_slice(nbr_teams)
#=> #<Enumerator:
# [{:name=>"Qasim", :rating=>1}, {:name=>"Usama", :rating=>2},
# {:name=>"Aj", :rating=>3}, {:name=>"Osman", :rating=>6},
# {:name=>"Mahsam", :rating=>7}, {:name=>"Bilal", :rating=>8},
# {:name=>"Owen", :rating=>15}, {:name=>"Kaka", :rating=>20}]
# :each_slice(4)>
我们可以将此枚举器转换为数组,以查看它将生成的对象并传递给map
。
b.to_a
#=> [[{:name=>"Qasim", :rating=>1}, {:name=>"Usama", :rating=>2},
# {:name=>"Aj", :rating=>3}, {:name=>"Osman", :rating=>6}],
# [{:name=>"Mahsam", :rating=>7}, {:name=>"Bilal", :rating=>8},
# {:name=>"Owen", :rating=>15}, {:name=>"Kaka", :rating=>20}]]
继续
c = b.map { |a| flip.next ? a.reverse : a }
#=> [[{:name=>"Osman", :rating=>6}, {:name=>"Aj", :rating=>3},
# {:name=>"Usama", :rating=>2}, {:name=>"Qasim", :rating=>1}],
# [{:name=>"Mahsam", :rating=>7}, {:name=>"Bilal", :rating=>8},
# {:name=>"Owen", :rating=>15}, {:name=>"Kaka", :rating=>20}]]
c.transpose
#=> [[{:name=>"Osman", :rating=>6}, {:name=>"Mahsam", :rating=>7}],
# [{:name=>"Aj", :rating=>3}, {:name=>"Bilal", :rating=>8}],
# [{:name=>"Usama", :rating=>2}, {:name=>"Owen", :rating=>15}],
# [{:name=>"Qasim", :rating=>1}, {:name=>"Kaka", :rating=>20}]]
可能希望将结果转换为哈希数组。
assign(4, players).map { |a| a.map { |h| [h[:name], h[:rating]] }.to_h }
#=> [{"Osman"=>6, "Mahsam"=>7},
# {"Aj" =>3, "Bilal" =>8},
# {"Usama"=>2, "Owen" =>15},
# {"Qasim"=>1, "Kaka" =>20}]
答案 1 :(得分:1)
我们可以解决通过按键等级对哈希进行排序的问题
players.sort_by { |k| k[:rating] }
现在对数组进行排序。
您最多可以迭代数组长度的一半,并在一个团队中推入i
元素和length-i
元素,在这种情况下,您有4个团队。
def divide_teams players
players = players.sort_by { |k| k[:rating] } # sorted
len = players.length
teams = Hash.new(0)
(len/2).times do |i|
teams["team#{i+1}"] = [players[i], players[len-i-1]]
end
teams
end
divide_teams players
=> {"team1"=>[{:name=>"Qasim", :rating=>1}, {:name=>"Kaka", :rating=>20}],
"team2"=>[{:name=>"Usama", :rating=>2}, {:name=>"Owen", :rating=>15}],
"team3"=>[{:name=>"Aj", :rating=>3}, {:name=>"Bilal", :rating=>8}],
"team4"=>[{:name=>"Osman", :rating=>6}, {:name=>"Mahsam", :rating=>7}]}
我假设现在有4个团队,每个团队中有2个成员。
如果职能团队是一个动态变量,则可以根据需要更改职能。
谢谢。