В посте #2 этого топика максимально простое и очевидное решение. Я правильно понимаю, что далее дискуссия ведется по поводу строки 11, из-за которой это решение теоретически может работать бесконечно долго?
|
Alexandroppolus,
дискуссии не было, полностью согласен что #2 простое решение и чем больше начальный массив, тем меньше "лишних" циклов вероятность, мне было интересно решить это как-то иначе. |
Я покрутил алгоритм из поста #2 со множеством из 20 элементов 1 000 000 раз.
Получил 2 лишних цикла. Как и положено по теории, с вероятностью 1/2^20 получаем последовательность из 20 случайных чисел, каждое из которых < 0.5 или >=0.5 Годный датчик случайных чисел |
чисто ради прикола докрутил #2, чтобы не было вероятности лишнего цикла
function splitSet(set) { const subs = [[], []]; for(let i = 0; i < set.length; i++) { subs[Math.round(Math.random())].push(set[i]); } if (!subs[0].length || !subs[1].length) { const srcIndex = subs[0].length ? 0 : 1; const index = Math.floor(Math.random() * set.length); subs[1 - srcIndex] = subs[srcIndex].splice(index, 1); } return subs; } for (let i = 0; i < 25; i++) { let [s1, s2] = splitSet([1,2,3,4,5,6,7]); console.log(s1, s2); } суть: если в одном из массивов пусто, из другого перекидываем случайно выбранный элемент. Это сохраняет равные шансы для каждого из элементов попасть в любой массив. Можно было бы перекидывать, допустим, первый элемент. Но тогда немного уменьшились бы его шансы оказаться вместе со вторым, хотя по отдельности и у первого, и у второго одинаковые шансы быть в любом из массивов. Этот "парадокс" я пока не осмыслил. |
Цитата:
Да, задачка хитрая) |
Часовой пояс GMT +3, время: 13:28. |