我想根据他们的评分将球员划分为个人公平的球队。例如,我有一个像这样的球员列表:
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整除。欢迎任何类型的答案:)
您可以按如下方式实现您描述的分配算法。
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}]
我们可以通过评级作为关键来解决它对哈希进行排序
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个成员。
如果功能团队是动态变量,您可以根据需要更改功能。
谢谢。