将数组分组,添加剩余的ruby

时间:2014-04-04 18:44:24

标签: ruby arrays

我有以下阵容的13名球员

players = ['andre','ben','cameron','deshawn','emmanuel','freddy','gabriel','henry','ian','jadeveon','kentavious','lance','malik']

我想要一种方法,使用类似于此的代码将玩家分成4人队:

def teams(array)
  groups = [] 
  array.shuffle.each_slice(4) { |group| groups << group } 
  groups
end

鉴于一系列玩家的长度不可分为4,如何将余数添加到现有群组?例如,如果我有13个玩家阵列,我如何输出2个4队和1个5队?等等22的数组...

预期输出

[['freddy','malik','cameron','deshawn','jadeveon'],['lance','kentavious','gabriel','ian'],['emmanuel','henry','ben','andre']]

4 个答案:

答案 0 :(得分:3)

groups = array.shuffle.each_slice(4).to_a
spares = groups.pop if groups[-1].size != 4
spares.each_with_index{|p,i| groups[i]<<p}

答案 1 :(得分:1)

编辑:我要感谢@AShelly在原始解决方案中发现一个漏洞,并指出我的代码在11名玩家时产生的结果不正确。事实证明,它给我提供的所有例子都产生了错误的答案,但显然没有人注意到。我在each_slice(players.size/4)以下,我以前有过each_slice(4)。我相信代码现在还可以。

<强>代码

def deal_players(players)
  shuffled = players.shuffle
  shuffled.shift(4*(players.size/4)).each_slice(players.size/4).map { |g|
    shuffled.any? ? g + [shuffled.shift] : g }
end

<强>实施例

players = ['andre','ben','cameron','deshawn','emmanuel','freddy',
           'gabriel','henry','ian','jadeveon','kentavious']

deal_players(players)
  #=> [["emmanuel", "jadeveon"  , "gabriel"],
  #    ["cameron" , "henry"     , "ben"    ],
  #    ["freddy"  , "kentavious", "ian"    ],
  #    ["deshawn" , "andre"                ]]

players = ['andre','ben','cameron','deshawn','emmanuel','freddy','gabriel',
           'henry','ian','jadeveon','kentavious','lance','malik','betty']

deal_players(players)
   #=> [["betty"   , "ian"   , "henry"  , "kentavious"],
   #    ["ben"     , "freddy", "deshawn", "malik"     ],
   #    ["emmanuel", "lance" , "cameron"              ],
   #    ["gabriel" , "andre" , "jadeveon"             ]]

<强>解释

players = ['andre','ben','cameron','deshawn','emmanuel','freddy','gabriel',
           'henry','ian','jadeveon','kentavious','lance','malik']

shuffled = players.shuffle
  #=> ["ben", "henry", "lance", "emmanuel", "malik", "cameron", "freddy",
  #    "deshawn", "andre", "jadeveon", "kentavious", "gabriel", "ian"]

a = shuffled.shift(4*(players.size/4))
  #=> ["ben", "henry", "lance", "emmanuel", "malik", "cameron", "freddy",
  #   "deshawn", "andre", "jadeveon", "kentavious", "gabriel"]

shuffled #=> ["ian"]

b = a.each_slice(players.size/4)
  #=>#<Enumerator:["ben","henry","lance","emmanuel","malik","cameron","freddy",
  #    "deshawn","andre","jadeveon","kentavious","gabriel"]:each_slice(3)>

查看枚举器的内容:

b.to_a
  #=> [["ben"     , "henry"     , "lance"  ],
  #    ["emmanuel", "malik"     , "cameron"],
  #    ["freddy"  , "deshawn"   , "andre"  ],
  #    ["jadeveon", "kentavious", "gabriel"]]

b.map { |g| shuffled.any? ? g + [shuffled.shift] : g }
  #=> [["ben"     , "henry"     , "lance", "ian"],
  #    ["emmanuel", "malik"     , "cameron"     ],
  #    ["freddy"  , "deshawn"   , "andre"       ],
  #    ["jadeveon", "kentavious", "gabriel"     ]]

最后一步只是将shuffled中剩余的一个玩家(0到3之间)添加到b的每个数组元素中,直到不再添加为止。在这里,shuffled仅包含&#34; ian&#34;,所以&#34; ian&#34;被添加到第一组。

答案 2 :(得分:1)

不是最简洁的解决方案,但这应该有效:

 if team.length%num == 0
    teams = team.each_slice(num).to_a
  else
    total = (team.length).divmod(num)       //returns array[0]=quotent, array[1]=remainder
    extra_players= team.shift(total[1]) 
    final_teams = team.each_slice(total[0]).to_a
    remainder_players.each do |x| 
      final_teams.sample.push(x)                 
    end
  end

答案 3 :(得分:0)

我在这个游戏上迟到了,但是我几乎在做同样的事情。 (另加扭曲)。 将一组未知的大小(我定义为> 11,但也可以使用较小的数字)排序为不超过5个的小组(> 11为5或4的小组)。 我抓起一副纸牌,从纸牌上剪下随机数。 计算切割的大小,然后除以5,并四舍五入到最接近的整数。 在上面的示例中,11/5 = 2.2,四舍五入为3,以确定团队数。 现在只需将卡片分成3堆,最后便得到4、4和3堆(团队)。 再次,大于11的数字将全部为5或4的团队。

    我的转折点是我需要根据每只手的总价值来平衡每只手/桩/团队。我会将其发布为新问题。