2015-04-14 2 views
0

Я пытаюсь написать рутину, которая в основном делает «посев» для команд, как и недавний турнир по баскетболу NCAA, применяется к командам для гольфа, где часто бывает странно количество игроков. Баскетбол легко, есть 64 команды и 4 скобки, а самое высокое семя - самое низкое семя. Мой немного сложнее.Ищете подход к созданию сборных гольф-команд для мини-турнира

Если у меня есть 13 игроков, которые появятся на игру, там будет 4 команды, 1 четверка и 3 тройки. Игроки будут отсортированы по квоте/гандикапу. Игрок 1 является самым высоким игроком, а игрок 13 является самым низким. Цель состоит в том, чтобы навыки каждой команды распределялись как можно более равномерно. У меня на самом деле это работает, но это действительно уродливый код, и я пытаюсь перефразировать его во что-то похожее на рубин вместо базового!

Я использовал несколько вариантов массивов. Если я начинаю с массивом из 13 игроков:

[1,2,3,4,5,6,7,8,9,10,11,12,13] 

Я могу разбить его на семена, первое, чтобы заботиться о четверке (обычно называемые ABCD группы)

[[1,2,3,4],[5,6,7],[8,9,10],[11,12,13]] 

Чтобы получить даже распределение, самый высокий игрок в группе А будет играть с самым низким игроком в группе B, самым высоким игроком в группе C и самым низким игроком в группе D. После того, как четверка сформирована, остальные игроки будут группами в 3 семени, ABC и некоторый тип подпрограммы, применяемой к 3 группам. Она заканчивающиеся команды будет:

[[1,7,8,13]] # foursome, 1st team 
[[2,3,4],[5,6,9],[10,11,12]] # remaining players ofter first team formed and seeded into 3 group 

С тройкой, я бы поставил самый высокий игрок в группе А с самым низким игроком в группе В и высшей игрок в группе C. Окончательные результаты должны быть что-то подобное.

[[1,7,8,13],[2,9,10],[3,6,11],[4,5,12]] 

Если у вас 15 игроков показать, что будет 3 и 1 четверки втроём и вы получите команды хотели.

[[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15]] 
[[1,8,9,15],[2,7,10,14],[3,6,11,13],[4,5,9]] 

Мой метод высева достаточно сложен, и все перенесение, поппинг и уплощение формировать команды хуже. Мне просто интересно, есть ли у кого-нибудь предложения по другому подходу.

def seed_sample(count,make_up='') 
    players = [] # init an empty array 
    1.upto(count) do |i| 
    players << i 
    end # => [1,2,3,4,5,6,...,count] 
    abcd = [] #init empty seed array 
    if make_up == 'foursomes' 
    4.times{abcd << players.shift(count/4)} 
    elsif make_up == 'threesomes' 
    3.times{abcd << players.shift(count/3)} 
    elsif make_up == 'twosomes' 
    2.times{abcd << players.shift(count/2)} 
    else #mixed 
    a_pop = (count/4) + 1 # number of a players to put in seed stack 
    abcd << players.shift(a_pop) # A players, always first 
    rem = players.count # s array is reduced by a_pop, so get count 
    if rem.modulo(3).zero? 
     3.times{abcd << players.shift(rem/3)} # B & C & D players 
    elsif rem.modulo(3) == 1 
     abcd << players.shift(a_pop) # B players 
     2.times{abcd << players.shift(rem/3)} # C & D players 
    else # rem.modulo(3) == 2 
     2.times{abcd << players.shift(a_pop)}# B & C players 
     abcd << players # remainder = D players 
    end 
    end 
    @seeds = abcd 
return abcd 
end 

Принимая предложения от RyanK, я уже в пути. Ниже приведен пример тестового семенного метода, который также формирует команды. Вся информация известна из класса, поэтому мне просто нужно заменить около 100 строк кода, если только это не может быть улучшено.

def test_seed(count,fours=nil,threes=nil,twos=nil) 
    players = Array(1..count) # => [1,2,3,4,5,6,...,count] 
    abcd = [] #init empty seed array 
    fours.times{abcd << players.shift(4)} if fours.present? 
    threes.times{abcd << players.shift(3)} if threes.present? 
    twos.times{abcd << players.shift(2)} if twos.present? 
    abcd.each_index do |s| # reverse odd stacks to distribute skills 
    unless s.modulo(2).zero? 
     abcd[s].reverse! 
    end 
    end 
    # shuffle stacks by taking card off top of each stack 
    seeded = [] 
    abcd.count.times do 
    abcd.each_index do |i| 
     seeded << abcd[i].shift if abcd[i].present? 
    end 
    end 
    # now lets put the teams together 
    @teams = [] 
    fours.times{@teams << seeded.shift(4)} if fours.present? 
    threes.times{@teams << seeded.shift(3)} if threes.present? 
    twos.times{@teams << seeded.shift(2)} if twos.present? 
    return abcd,seeded, @teams 
end 
+0

Не было бы проще равномерно разделить их (как можно лучше) по одному, вроде как раздавать игровые карты в карточной игре? Таким образом, ваш пример превратится в '[[1,5,9,13], [2,6,10], [3,7,11], [4,8,12]]'. –

+0

Мне нужно подумать об этом немного. Проблема заключается в «равномерном разделении» без кучи кода. Если я смогу очистить получение [[1,2,3,4], [5,6,7], [8,9,10], [11,12,13]], я мог бы изменить второй и четвертый элементы и раздайте 1 карту из каждого стека. Мы на самом деле использовали карты для создания команд вручную, но это было случайным, а не посеянным. Что мне нужно, это сложная колода! – appleII717

ответ

0

Итак, вот несколько способов, чтобы сделать свой код (который работает, вы говорите) лучше:

def seed_sample(count,make_up='') 
    players = (1..count).to_a 
    abcd = [] #init empty seed array 
    num = 0 
    if make_up == 'foursomes' 
    num = 4 
    elsif make_up == 'threesomes' 
    num = 3 
    elsif make_up == 'twosomes' 
    num = 2 
    else 
    return 
    end 
    abcd << players.shift((count/num.to_f).ceil) while players.count > 0 

    abcd[1],abcd[3] = abcd[3],abcd[1] #Flip the second and fourth sub-arrays 
    #Of course, always assumes 4 groups and max of 16 people 

    @seeds = [[],[],[],[]] 
    abcd.each_with_index do |value, index| 
    4.times {|i| @seeds[i] = value[index]} 
    end 
return @seeds 
end 

Это должно, по крайней мере, чтобы вы начали. Эта последняя часть, о которой я не уверен, так что протестируйте ее и убедитесь, что она работает.

0

Я принял другой подход и сначала отсортировал всех игроков (где # 1 был лучшим, а №13 - худшим), а затем использовал фрагменты для вывода команд.

# Seed class 
# Initialize with count of all players and make up of first team 
# Sorts all of the players in pairs with the best and worst player 
# as the first pair 

class Seed 
     attr_accessor :count, :make_up 

    def initialize(count, make_up) 
     @count = count 
     @make_up = make_up 
    end 

    def run 
     sorted_array = sort 
     first_team(sorted_array) 
     other_teams(sorted_array) 
    end 

    def sort 
     arr = ([email protected]).to_a 
     arr_new = [] 
     sorting_iteration = (@count/2) + 1 
     sorting_iteration.times do 
      arr_new << arr.shift 
      arr_new << arr.pop unless arr.size == 0 
     end 
     arr_new 
    end 

    def first_team(sorted_array) 
     p sorted_array.slice(0, @make_up) 
    end 

    def other_teams(sorted_array) 
     all_others = sorted_array.slice(@make_up, @count) 
     all_others 
     other_make_up = @make_up - 1 
     p all_others.each_slice(other_make_up) { |a| p a } 
    end 

end 

round = Seed.new(13, 4) 
round.run 
0

Вероятно, не будет лучшего ответа, так как я просто просил подход. Я также оставил много информации. Вы можете не только иметь смешанные команды, вы можете иметь всех четверо, всех втроем, всех двоих и даже людей в команде.У вас может быть всего 3 или 4 игрока, и я видел его за 30.

Спасибо за предложения. У меня отредактированная тестовая программа была проблема, и через несколько дней, играя с колодой карт, я придумал следующий класс. Он управляется параметрами, предоставляемыми пользователем в классе «Команды» и переданными Seed.

class Seed 
    # usage 
    # input a set of parameter build from selection of team formation options 
    # output an ordered array of seeds that match selection options 
    # params example 
    # {:team_makeup=>"mixed", :seed_method=>"seeded", :count=>13, :teams=>4, :teetimes=>4, 
    #  :foursomes=>1, :threesomes=>3, :twosomes=>nil, :seed_size=>4, :first_size=>1} 
    attr_accessor :count, :params, :seeded 

    def initialize(seed_params) 
    @params = seed_params 
    @seeded = [] 
    end 

    def build_seeded_array 
    players = Array([email protected][:count]) # => [1,2,3,4,5,6,...,count] 
    seeds = seed_players(players) 
    @seeded = seeds_to_seeded(seeds,@params[:seed_size],@params[:first_size]) 
    end 

    def seed_players(players,size=nil) 
    seeds = [] #init empty seed array 
    size = size ||= @params[:seed_size] 
    players_count = players.count 
    shift_size = players_count/size 
    remaining = players_count.modulo(size) 
    size.times{seeds << players.shift(shift_size)} 
    # with mixed teams, there will be players left, shift to last seed, then distribute all seeds 
    players.count.times{seeds[-1] << players.shift} 
    seeds = shift_seeds(seeds,remaining) unless remaining.zero? 
    seeds 
    end 

    def seeds_to_seeded(seeds,seed_size,numb) 
    seeded = seeded_seeds(seeds,numb) 
    players = seeds.flatten.sort 
    unless players.blank? 
     seed_size -= 1 
     numb = players.count/seed_size 
     seeds = seed_players(players,seed_size) 
     seeded << seeded_seeds(seeds,numb) 
    end 
    seeded.flatten 
    end 

    def seeded_seeds(seeds,numb) 
    seeds = distribution_swap(seeds) 
    seeded = [] 
    numb.times do 
     seeds.each_index do |i| 
     seeded << seeds[i].shift if seeds[i].present? 
     end 
    end 
    seeded 
    end 

    def distribution_swap(seeds) 
    seeds.each_index do |s| # reverse odd stacks to distribute skills 
     unless s.modulo(2).zero? 
     seeds[s].reverse! 
     end 
    end 
    seeds 
    end 

    def shift_seeds(seeds,remaining) 
    # mixed team will stack last seed, need to shift them. 
    # [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16, 17, 18, 19]] 
    # [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19]] 
    return(seeds) if @params[:foursomes].blank? 
    if remaining == 3 
     3.times{seeds[-2] << seeds[-1].shift} 
     2.times{seeds[-3] << seeds[-2].shift} 
     1.times{seeds[-4] << seeds[-3].shift} 
    elsif remaining == 2 
     2.times{seeds[-2] << seeds[-1].shift} 
     2.times{seeds[-3] << seeds[-2].shift} 
     1.times{seeds[-4] << seeds[-3].shift} 
    else 
     1.times{seeds[-2] << seeds[-1].shift} 
     1.times{seeds[-3] << seeds[-2].shift} 
     1.times{seeds[-4] << seeds[-3].shift} 
    end 
    seeds 
    end 

end 
Смежные вопросы