Входные данные: два целых числа n и k, заданные в любой форме, удобной для вашего кода
Выходные данные Случайная неубывающая последовательность из k целых чисел, каждое из которых находится в диапазоне от 1 до n. Выборка должна выбираться равномерно из всех неубывающих последовательностей из k целых чисел с целыми числами в диапазоне от 1 до n.
Вывод может быть в любом удобном для вас формате.
Вы можете использовать любой псевдослучайный генератор, который предоставляет ваша любимая библиотека / язык.
Можно предположить, что целые числа n, k> 0.
пример
Скажите n, k = 2. Неубывающие последовательности
1,1
1,2
2,2
Каждая последовательность должна иметь вероятность 1/3 вывода.
ограничение
Ваш код должен выполняться не более, чем за несколько секунд для k = 20 и n = 100.
Что не работает
Если вы просто случайным образом выберете каждое целое число из диапазона от 1 до n, а затем отсортируете список, вы не получите равномерного распределения.
источник
Ответы:
На самом деле ,
1412 байтЭтот ответ основан на 05AB1E ответ Emigna в и ответов на этот вопрос Math.SE . Предложения по игре в гольф приветствуются! Попробуйте онлайн!
Ungolfing
источник
Python, 89 байт
Генерация возрастающей последовательности, а не неубывающей, была бы простой: это просто случайное подмножество
k
чисел между1
иn
, отсортированными.Но мы можем преобразовать возрастающую последовательность в неубывающую, уменьшив каждый разрыв между последовательными числами на 1. Таким образом, разрыв 1 становится разрывом 0, делая равные числа. Для этого уменьшите
i
наибольшее значение наi
Чтобы результат был от
1
доn
, входные данные должны быть от1
доn+k-1
. Это дает биекцию между неубывающими последовательностями чисел между1
иn
, к увеличивающимся последовательностям между1
иn+k-1
. Та же биекция используется в аргументе звезд и столбцов для подсчета таких последовательностей.В коде используется функция python
random.sample
, которая беретk
образцы без замены из списка ввода. Сортировка дает возрастающую последовательность.источник
import*
можете сэкономить 1 байт)05AB1E , 13 байтов
Попробуйте онлайн!
объяснение
источник
Python, 87 байт
Вероятность включения максимально возможного значения
n
равнаk/(n+k-1)
. Чтобы включить его, поместите его в конец списка и уменьшите оставшиеся необходимые числаk
. Чтобы исключить это, уменьшите верхнюю границуn
. Затем повторяйте до тех пор, пока значения больше не понадобятся (k==0
).В Python,
random
похоже, нет встроенной переменной Бернулли: 1 с некоторой вероятностью и 0 в противном случае. Таким образом, это проверяет,random
падает ли ниже случайное значение между 0 и 1, сгенерированное какk/(n+k-1)
. Python 2 будет отношение , как поплавок деление, таким образом , мы вместо того, чтобы умножить на знаменатель:k>random()*(n+k-1)
.источник
numpy.random
, что слишком долго.JavaScript (Firefox 30+), 74 байта
объяснение
Отличный ответ xnor на Python содержит очень хорошее резюме того, как / почему работает техника, используемая здесь. Первым шагом является создание диапазона [1, 2, ..., n + k - 1] :
Далее нам нужно взять k случайных предметов из этого диапазона. Чтобы сделать это, нам нужно выбрать каждый элемент с вероятностью s / q , где s - количество элементов, которые все еще необходимы, а q - количество элементов, оставшихся в диапазоне. Поскольку мы используем понимание массива, это довольно просто:
Это дает нам равномерно распределенную возрастающую последовательность чисел. Это можно исправить, вычтя количество найденных ранее элементов j :
Наконец, сохраняя k в j , мы можем включить
k--
в выражение и сохранить несколько байтов:источник
TI-BASIC, 54 байта
Следуйте логике xnor с небольшим предостережением. Мы можем теоретически побрить байт, выполнив что-то вроде этого:
Но rand (зарезервировано для создания списка случайных чисел, поэтому мы не сможем выполнить желаемое неявное умножение для сохранения байта.
Это должно работать прилично быстро на 84+ за ограничение, но я проверю, когда смогу.
источник
PHP,
777573 байтаЗапустите так:
объяснение
Tweaks
end()
вызова и набора$argv[2]
для$k
вместо того, чтобы сокращенный доступа к аргументам$i
каждую итерацию вместоисточник