Про серію
По-перше, ви можете ставитися до цього, як і до будь-якого іншого виклику коду для гольфу, і відповісти на нього, не турбуючись про серію взагалі. Однак існує лідери у всіх викликах. Ви можете знайти таблицю лідерів разом з додатковою інформацією про серію в першій публікації .
Хоча у мене є маса ідей, що вибудовуються для цієї серії, майбутні виклики ще не поставлені в камені. Якщо у вас є якісь пропозиції, будь ласка, повідомте мене про це у відповідній поштовій скриньці .
Отвір 3: Цілі перегородки
Час трохи збільшити труднощі.
Розбиття позитивного цілого числа n
, визначається як мультімножество позитивних цілих чисел, сума яких дорівнює n
. Як приклад, якщо n = 5
існують такі розділи:
{1,1,1,1,1}
{2,1,1,1}
{2,2,1}
{3,1,1}
{3,2}
{4,1}
{5}
Зауважте, що це мультисети, тому їх немає порядку {3,1,1}
, {1,3,1}
і {1,1,3}
всі вони вважаються ідентичними.
Ваше завдання задається n
генерувати випадковий розділ n
. Ось детальні правила:
Розподіл вироблених перегородок повинен бути рівномірним . Тобто, у наведеному вище прикладі кожен розділ повинен бути повернутий з вірогідністю 1/7.
Звичайно, через технічні обмеження PRNG досконала рівномірність буде неможливою. Для оцінки однорідності ваших заявок наступні операції будуть розглядатися як такі, що дають ідеально рівномірні розподіли:
- Отримання номера з PRNG (у будь-якому діапазоні), який задокументовано, щоб бути (приблизно) однорідним.
- Зображення рівномірного розподілу за більшим набором чисел на менший набір за модулем або множенням (або якась інша операція, яка розподіляє значення рівномірно). Більший набір повинен містити принаймні в 1024 рази більше можливих значень, ніж менший.
Оскільки розділи є мультисетами, ви можете повернути їх у будь-якому порядку, і це замовлення не повинно бути послідовним. Однак для випадкового розподілу порядок ігнорується. Тобто, в наведеному вище прикладі,
{3,1,1}
,{1,3,1}
і{1,1,3}
разом повинні мати можливість 1/7 повертається.- Ваш алгоритм повинен мати детермінований час виконання. Зокрема, ви не можете генерувати випадкові мультисети та відхиляти їх, якщо вони не підсумовують
n
. - Часова складність алгоритму повинна бути багаточлена
n
. Зокрема, ви не можете просто генерувати всі розділи та вибрати випадковий (оскільки кількість розділів зростає в експоненціальному масштабі)n
). Ви можете припустити, що PRNG, який ви використовуєте, може повертати рівномірно розподілені значення в O (1) на значення. - Ви не повинні використовувати будь-яку вбудовану функцію, яка вирішує цю задачу.
Ви можете написати повну програму або функцію та взяти вхід через STDIN або найближчу альтернативу, аргумент командного рядка або аргумент функції та виробляти висновок через повернене значення або друкуючи на STDOUT (або найближчу альтернативу).
Ви можете припустити, що n ≤ 65
(таким чином, що кількість розділів менше 2 21 ). Вихід може бути у будь-якому зручному, недвозначному списку чи рядковому форматі.
Якщо ви подаєте функцію, будь ласка, також слід передбачити невелику програму тестування, яка кілька разів викликає функцію та друкує результати. Це нормально, якщо параметри потрібно ввести в код. Це просто для того, щоб люди могли перевірити, що рішення є принаймні приблизно рівномірним.
Це код гольфу, тому виграє найкоротше подання (у байтах). І звичайно, найкоротше подання на кожного користувача також увійде в загальну таблицю лідерів серії.
Таблиця лідерів
Перший пост серії генерує таблицю лідерів.
Щоб відповіді відображалися, почніть кожну відповідь із заголовка, використовуючи такий шаблон Markdown:
# Language Name, N bytes
де N
розмір вашого подання. Якщо ви покращите свій рахунок, ви можете зберегти старі бали у заголовку, прокресливши їх. Наприклад:
# Ruby, <s>104</s> <s>101</s> 96 bytes
(Мова наразі не відображається, але фрагмент вимагає і аналізує його, і я можу в майбутньому додати таблицю лідерів за мовою.)