Случайность это весело. Проблемы без смысла весело.
Напишите функцию, которая при заданном целочисленном вводе n
выведет набор (неупорядоченный, уникальный) точно n
случайных целых чисел между 1
и n^2
(включительно) таким образом, чтобы сумма всех целых чисел была равна n^2
.
Случайность не обязательно должна быть равномерной, при условии, что каждый действительный набор имеет ненулевую вероятность возникновения.
Кратчайший ответ в байтах (на каждый язык) выигрывает.
Примеры
Input (n) = 1, Target (n^2) = 1
Sample of possible outputs:
1
Input = 2, Target = 4
Sample of possible outputs:
3, 1
1, 3
Input = 3, Target = 9
Sample of possible outputs:
6, 1, 2
3, 5, 1
4, 3, 2
Input = 4, Target = 16
Sample of possible outputs:
1, 3, 5, 7
2, 4, 1, 9
8, 3, 1, 4
Input = 5, Target = 25
Sample of possible outputs:
11, 4, 7, 1, 2
2, 3, 1, 11, 8
6, 1, 3, 7, 8
Input = 8, Target = 64
Sample of possible outputs:
10, 3, 9, 7, 6, 19, 8, 2
7, 16, 2, 3, 9, 4, 13, 10
7, 9, 21, 2, 5, 13, 6, 1
Бонусное задание: существует ли формула для расчета количества действительных перестановок для данного n
?
code-golf
random
combinatorics
Skidsdev
источник
источник
Ответы:
Brachylog (v2), 15 байтов (случайный) или 13 байтов (все возможности)
случайный
Попробуйте онлайн!
Представление функции (видно в TIO с оберткой, превращающей ее в полноценную программу).
объяснение
Все возможности
Попробуйте онлайн!
Функция представления, которая генерирует все возможные выходы.
объяснение
Я довольно удивлен, что это
∧≜
работает (вам, как правило, придется писать∧~≜
для того, чтобы перебрать выходные данные, а не входные данные), но оказывается, что≜
имеет предположение input = output, поэтому не имеет значения, в какую сторону вас обойти запустить его.Бонусное задание
Чтобы получить представление о последовательности числа возможностей, я создал другую оболочку TIO, которая запускает программу с последовательными целыми числами, чтобы получить последовательность выходных значений:
Поездка в OEIS обнаруживает, что это уже известная последовательность, A107379 , описанная почти так же, как в вопросе (очевидно, вы получите ту же последовательность, если вы ограничите ее нечетными числами). На странице перечислены несколько формул для последовательности (хотя ни одна из них не является особенно простой; вторая выглядит как прямая формула для значения, но я не понимаю обозначения).
источник
x^(n*(n-1)/2)
расширения в серииProduct_{k=1..n} 1/(1 - x^k)
» (к сожалению,A≠≜₁ᵐ
) делает время выполнения в среднем намного быстрее.05AB1E , 11 байт
Попробуйте онлайн или проверьте все контрольные примеры .
Объяснение:
источник
Python (2 или 3), 85 байт
Попробуйте онлайн!
источник
R ,
68, 7548 байтов (случайный) и 70 байтов (детерминированный)Метод выборки отклонения @ Джузеппе:
Попробуйте онлайн!
Гольф оригинал:
Попробуйте онлайн!
Задача
*!!1:2
состоит в том, чтобы избежать странныхsample
действий, когда первый аргумент имеет длину 1.источник
p
непосредственно в качестве индекса вместо вычисления и повторного использования должно сохранить некоторые байты.function(n){while(sum(F)!=n^2)F=sample(n^2,n);F}
48 ...sample(2,1)
что происходит сn=2
. Такrep
что просто гарантирует, что этого никогда не произойдет. Возможно, есть лучший способ, но это было быстро, и я был зол наsample
.x*!!1:2
более чем,rep(x,2)
если ваш мета-вопрос получает нет.Желе , 9 байт
Попробуйте онлайн!
Создайте все n-комбинации из списка [1..n²], отфильтруйте их с суммой n², затем выберите случайную.
источник
Java 10,
250242222 байта-20 байт благодаря @nwellnhof .
Остерегайтесь, Java приходит ... Это «всего» в пять раз дольше, чем остальные четыре ответа вместе взятые, так что, думаю, не так уж и плохо… rofl.
Он мчит
n=1
черезn=25
(комбинированный) менее чем за 2 секунды , хотя, так что я , вероятно , опубликовать измененную версию до версии скорости этой задачи (которая в настоящее время все еще находится в песочнице) , а также.Попробуйте онлайн.
Объяснение:
В псевдокоде мы делаем следующее:
1) Создание массива размера ,
n+1
содержащий:0
,n
квадрат, аn-1
количество случайных чисел в диапазоне от[0, n squared)
2) Сортировки этого массива
3) создать второй массив размера ,
n
содержащий вперед различие парЭтого первые три шаг даст нам массив , содержащий
n
случайный образ целые числа (в диапазоне[0, n squared)
от суммы доn
квадрата.4a) Если не все случайные значения уникальны или любое из них равно 0: повторите попытку с шага 1
4b) Остальное: вернуть этот массив разностей в качестве результата
Что касается фактического кода:
источник
n=25
менее чем за 2 секунды впечатляет! Я должен прочитать объяснение и посмотреть, как оно это делает. Это все еще метод грубой силы?[0, n squared)
сначала получить случайные значения в диапазоне , а затем вычисляет различия между этими отсортированными случайными значениями (включая начальное0
и конечное значенияn squared
. Поэтому я почти уверен, что эти различия также одинаковы. Но снова Я не уверен, как это доказать. Равномерность в случайности на самом деле не моя экспертизаd
или я что-то упустил?Perl 6 , 41 байт
Попробуйте онлайн!
(1 .. $_²)
диапазон чисел от 1 до квадрата входного числа.pick($_)
случайным образом выбирает отдельное подмножество этого диапазонаxx *
повторяет предыдущее выражение бесконечноfirst *.sum == $_²
выбирает первый из этих наборов чисел, который суммируется с квадратом входного числаисточник
Pyth,
1312 байтПопробуйте это онлайн здесь . Обратите внимание, что онлайн-интерпретатор сталкивается с MemoryError для входных данных больше 5.
Изменить: сохранить байт, используя альтернативный подход. Предыдущая версия:
Of&qQlT{IT./*
источник
Python 3 ,
136 134 127 121114 байтовПопробуйте онлайн!
Меня поправил комментатор, и теперь он достигает максимальной глубины рекурсии при f (5) вместо f (1). Намного ближе к тому, чтобы быть реальным конкурирующим ответом.
Я видел, как это делает f (5) один раз , и я работаю над тем, чтобы реализовать это с помощью shuffle.
Я попытался сделать несколько лямбда-выражений для
s=...
, но это не помогло в байтах. Может быть, кто-то еще может что-то сделать с этим:s=(lambda n:{randint(1,n*n)for _ in range(n)})(n)
Спасибо Кевину за то, что он сбрил еще 7 байтов.
источник
f(1)
, единственный возможный массив, который должен быть сгенерирован,n=1
это[1]
также много лишних пробелов, которые нужно удалить здесь. Помните, что это сложная задача для игры в гольф, поэтому цель состоит в том, чтобы достичь наименьшего количества участниковrange(1,n)
->range(n)
Я считаю, должен устранить ошибку.return len(s)==n and sum(s)==n*n and s or f(n)
( Попробуйте онлайн 114 байтов ).APL (Dyalog Unicode) , 20 байтов SBCS
Анонимный префикс лямбда.
Попробуйте онлайн!
{
…}
"Дфн";⍵
это аргумент⍵*2
приводить аргументыs←
назначитьs
(для s quare)⍵?
найтиn
случайные индексы от 1…s
без заменыc←
назначитьc
(для c andidate)+/
суммировать ихs=
по сравнению сs
:
если равноc
вернуть кандидата⋄
еще∇⍵
повторять аргументисточник
APL (Dyalog Classic) , 18 байт
Попробуйте онлайн!
использования
⎕io←1
⍳
генерирует числа1 2 ... n
(
...)⍣(
...)
продолжайте применять функцию слева, пока функция справа не вернет true≢
длина, т.е.n
≢?≢×≢
выбирайте случайноn
разные целые числа от 1 доn
2+.-∘≢
вычтите длину из каждого числа и суммы0=
если сумма равна 0, остановите цикл, в противном случае попробуйте сноваисточник
MATL ,
1813 байтПопробуйте онлайн!
источник
Japt, 12 байт
Попытайся
источник
à
должен быть в порядке.Java (JDK) , 127 байт
Попробуйте онлайн!
Бесконечный цикл до совпадения набора с критериями.
Я надеюсь, у вас есть время, потому что это очень круто! Это даже не может идти до 10 без времени ожидания.
источник
if(r.size()==n&s==0)
наif(r.size()+s==n)
.s>0
, пока размер может быть больше, чемn
. Хорошо, в этом случае это действительно не работает.n
является константой, но, к сожалению, обаs
иr.size()
являются переменными, которые могут быть как ниже, так и выше0
иn
соответственно.Пакет,
182145 байтовОбъяснение: Вычисляет минимально и максимально допустимый выбор, учитывая, что числа должны быть выбраны в порядке убывания, и выбирает случайное значение в пределах диапазона. Пример для ввода
4
:источник
JavaScript,
647291261260259251239 байтСпасибо @Veskah за -10 байт в оригинальной версии и «О, да, вы выводите все наборы, тогда как для вызова требуется случайный набор»
Попробуйте онлайн!
Создайте массив
n^2
индексов на основе 1, случайным образом отсортируйте массив, нарежьтеn
элементы из массива. При этом сумма случайных элементов не равнаn^2
циклу массива случайных элементов; если сумма элементов массива больше чемn^2
и текущий элемент-1
не равен нулю или текущий элемент-1
не находится в текущем массиве, вычтите1
; если сумма массива меньше, чемn^2
текущий элемент+1
отсутствует в массиве, добавьте1
к элементу. Если сумма массива равнаn^2
разрывному циклу, выведите массив.источник
k++
while
вероятно, также можно сократить до тела одной функции, которая принимает параметры; и может заменить условные операторы (троичные) дляif..else
операторов; среди других частей кода, которые, скорее всего, могут быть скорректированы для гольфа; например, удалениеlet
заявлений.if..else
n
?» , тестирование , если алгоритм последовательно возвращенное ожидаемый результат дляn^2
вывода массивов , генерируемых в одном вызове функции, и одновременно с учетом сходства на этот вопрос N-мерный N ^ N массив заполнен N .Japt , 20 байт
Попробуйте онлайн!
Чрезвычайно сильно использует «неравномерную» случайность, почти всегда выводит первые
n
нечетные числа, которые суммируются сn^2
. Теоретически он может вывести любой другой допустимый набор, хотя я смог подтвердить это только для малогоn
.Объяснение:
источник
Рубин , 46 байт
Попробуйте онлайн!
источник
C (gcc) ,
128125 байтовПопробуйте онлайн!
-3 байта благодаря потолку
ПРИМЕЧАНИЕ: вероятность очень очень далеко от равномерной. См. Объяснение того, что я имею в виду, и лучший способ проверить, работает ли он (сделав распределение ближе к равномерному [но все еще очень далеким от него]).
Как?
Основная идея состоит в том, чтобы выбирать только увеличивающиеся числа, чтобы не беспокоиться о дубликатах. Всякий раз, когда мы выбираем число, у нас есть ненулевой шанс «пропустить» его, если это допустимо.
x
k
y
x
Тем не менее логика заключается в том, чтобы иметь возможность отбросить любое,
y
которое удовлетворяет приведенному выше уравнению.Код
Уловка, которую я упомянул для лучшего тестирования кода, заключается в замене
rand()&&
наrand()%2&&
так, что есть вероятность 50-50, что любой заданный y будет пропущен, а не 1,RAND_MAX
если любой заданный y будет использован.источник
p(y),x-=y++)while(rand()&&(i-n)*((~n+i)/2+~y)+y<x)y++;
вместо){while(rand()&&(n-i)*(n-i+1)/2+(n-i)*(y+1)+y<x)y++;p(y);x-=y++;}
Чисто , 172 байта
Попробуйте онлайн!
источник
Python (2 или 3), 84 байта
Попробуйте онлайн!
Максимальная глубина рекурсии достигает около l (5)
источник
Котлин , 32 байта
Попробуйте онлайн!
источник
Mathematica 40 байтов
источник
RandomChoice@IntegerPartitions[#^2,{#}]&
Wolfram Language (Mathematica) , 49 байтов
Попробуйте онлайн!
Гольф версия от @ J42161217.
Wolfram Language (Mathematica) , 62 байта
Попробуйте онлайн!
Как это работает
Ответ на Бонусное задание
что в Mathematica:
Попробуйте онлайн!
источник
(While[Tr[s=RandomSample[Range[#^2],#]]!=#^2];s)&