Готовлю новогоднюю вечеринку с друзьями, решили сыграть в тайного санту. Но до нового года не встречаемся, поэтому жеребьевка удаленно. Захотелось поиграться с кодом, вышел вот такой:
Secret Santa Algorithm
Цель - рандомно раскидать кто кому дарит подарок, так, чтобы не вышло ситуации, что человек дарит самому себе)
Смущает наличие костыля
if (j + 1 == guests.get(j))
Как думаете, что можно улучшить? Ожидается лаконичный, простой, не зависающий на большом количестве участников, выполняющий свою задачу алгоритм.
import java.util.*;
class Rextester {
public static void main(String args[]) {
int GUESTS_NUMBER = 10;
List<Integer> guests = new ArrayList<>();
for (int i = 0; i < GUESTS_NUMBER;) {
guests.add(++i);
}
boolean shuffled = false;
outer:
while (!shuffled) {
Collections.shuffle(guests);
shuffled = true;
for (int j = 0; j < guests.size(); j++) {
if (j + 1 == guests.get(j)) {
shuffled = false;
continue outer;
}
}
}
for (int j = 0; j < guests.size(); j++)
System.out.println(j + 1 + " gives a gift to -> " + guests.get(j));
}
}
А почему бы не сделать так?
n
.{ 1, 2, ..., n }
и перетасовать её (Collections.shuffle
)Алгоритм генерирует просто цикл длины n
. Особенность — никогда не будут сгенерированы несколько коротких циклов, всегда только один длинный.
В Вашем алгоритме можно в цикле сделать проверку, если дарим самому себе, меняемся со следующим в очереди, если последний то с первым. Вот мой вариант:
public class Test {
public static void main(String args[]) {
int SANTA_NUMBERS = 10;
List<Integer> santaList = new ArrayList<>();
for (int i = 0; i < SANTA_NUMBERS; ) {
santaList.add(++i);
}
List<Integer> guests = new ArrayList<>(santaList);
Collections.shuffle(guests);
//в этом цикле проверяем
for (int i = 0; i < santaList.size(); i++) {
if (santaList.get(i) == guests.get(i)) {
if (i + 1 < santaList.size()){
Integer receiver = guests.get(i + 1);
guests.set(i + 1, guests.get(i));
guests.set(i , receiver);
}else {
Integer receiver = guests.get(1);
guests.set(1, guests.get(i));
guests.set(i , receiver);
}
}
}
for (int j = 0; j < santaList.size(); j++)
System.out.println(santaList.get(j) + " gives a gift to -> " + guests.get(j));
}
}
Оборудование для ресторана: новинки профессиональной кухонной техники
Частный дом престарелых в Киеве: комфорт, забота и профессиональный уход
Есть в проекте одна проблема, которая решается двумя способамиНо я не могу оценить какой способ будет "дешевле" для памяти
Добрый деньПрограмма должна выдавать ключ и несколько значений по этому ключу, но значения выводятся в виде кода: [{Person@1b6d3586=[Phone@4554617c, Phone@74a14482]}]...