Чтобы не возникало вопросов, о том как происходил подсчет результатов конкурса, я привожу к сведению читателей листинг программы, которая определяла победителей. Вполне возможно, когда-нибудь к данному коду будет прикручен удобный интерфейс и этим делом можно будет пользоваться “из коробки”, но пока можно посмотреть итак.
Для удобства восприятия, разобью код на несколько частей, и прокомментирую каждую из них. Если вы с 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 "Надеюсь вам понравилось! Оставляйте свои комментарии ниже"