Как считать победителей?

Чтобы не возникало вопросов, о том как происходил подсчет результатов конкурса, я привожу к сведению читателей листинг программы, которая определяла победителей. Вполне возможно, когда-нибудь к данному коду будет прикручен удобный интерфейс и этим делом можно будет пользоваться “из коробки”, но пока можно посмотреть итак.

Для удобства восприятия, разобью код на несколько частей, и прокомментирую каждую из них. Если вы с ruby не на дружеской ноге, то все равно можно смотреть “под кат”, поскольку думаю что пример будет понятен и без особых познаний синтаксиса.


# массив голосовавших 
participants = ['pashira', 'martishka', 'life_is_mistery', 'avinamor', 'megvaer']
# начальные данные - все в равных условиях
weights = { 'pashira' => 1.0, 'martishka' => 1.0, 'life_is_mistery' =>
1.0, 'avinamor' => 1.0, 'megvaer' =>1.0}

votes = {}
votes['pashira']         = ['life_is_mistery', 'megvaer']
votes['martishka']       = ['life_is_mistery']
votes['life_is_mistery'] = ['avinamor']
votes['avinamor']        = ['megvaer']
votes['megvaer']         = ['avinamor']

В этом блоке задаются начальные данные, список участников и кто за кого голосовал.


def fact(n)
        if n>0
                n*fact(n-1)
        else
                1
        end
end

quantity = participants.size
number = fact(quantity)

Небольшая функция определяющая число перестановок (number) для определенного количества участников (quantity). Число перестановок, в моем случае, факториал от количества элементов.


number.times do |iterator|
# Интересный блок - перетасовка участников в списке
swap = iterator%quantity
participants[participants.size] = participants[ swap ]
participants = participants[0..swap-1].to_a + participants[swap+1..quantity].to_a
# После перетасовки в списке сохраняется новый порядок участников

Казалось бы, что массив нам не сильно нужен, но дело в том, что ассоциативные массивы, в которых хранится вес голоса, каждого участника не сохраняют порядок элементов, а поскольку перебор всегда ведется в одном порядке, то и логично, что победил бы тот, кто находится на последнем месте в списке участников.


        participants.each do |who|
                whom = votes[who]
                weight_delta = weights[who]/(whom.size+1)
# Для каждого из участников определяется вес его голоса
                whom.each do |person|
                        weights[person] += weight_delta
# И увеличивается вес голосов тех, за кого он голосовал
                end
        end

puts weights.sort_by { |key, value| value }.reverse
# Выводится список результатов упорядоченный по весу

Также файлик доступен целиком в альтернативной расцветке


puts "Надеюсь вам понравилось! Оставляйте свои комментарии ниже"

Leave a Reply

Your email address will not be published. Required fields are marked *