Я прочитал этот вопрос и подумал, что это будет хорошим испытанием.
задача
Дайте вход 0<n<10
генерировать случайное число с
- ровно n цифр
- первый не
0
- так
f(n)>10**(n-1)-1
- так
- отличные цифры
Критерии победы
Это код-гольф, поэтому выигрывает самый короткий код.
случайный
Я имею в виду равномерно распределенные случайные. Таким образом, с точки зрения программы каждый возможный номер имеет одинаковую вероятность. Если язык, на котором вы пишете, имеет странный генератор случайных чисел, то можно использовать его.
пример
Список значений для случайного выбора n=2
:
[10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98]
code-golf
number
random
grid
game
king-of-the-hill
javascript
code-golf
arithmetic
statistics
code-golf
math
code-golf
math
code-golf
string
palindrome
code-golf
string
interactive
code-golf
quine
polyglot
code-golf
string
stack-exchange-api
code-golf
number-theory
decision-problem
code-golf
tips
code-golf
string
internet
code-golf
graphical-output
image-processing
fractal
code-golf
ascii-art
geometry
hexagonal-grid
code-golf
string
restricted-source
hello-world
code-golf
game
code-golf
cipher
code-golf
permutations
cops-and-robbers
permutations
cops-and-robbers
code-golf
internet
stack-exchange-api
code-golf
ascii-art
random
code-golf
tips
code-golf
ascii-art
code-golf
code-golf
kolmogorov-complexity
code-golf
string
unicode
code-golf
number
sequence
primes
palindrome
code-golf
game
decision-problem
code-golf
math
geometry
code-golf
graphical-output
interactive
code-golf
set-partitions
code-golf
number
arithmetic
restricted-source
code-golf
decision-problem
python
recursion
code-golf
ascii-art
code-golf
source-layout
code-golf
function
recursion
functional-programming
code-golf
game
combinatorics
permutations
code-golf
string
file-system
code-golf
string
hashing
code-golf
stack-exchange-api
code-golf
string
code-golf
math
number
arithmetic
polyglot
Роман Греф
источник
источник
Ответы:
Python 2 , 77 байт
Попробуйте онлайн!
Перемешивает список из 10 цифр до тех пор, пока он не начинается с 0, а затем создает число с указанными первыми
n
цифрами.источник
9
или10
.[1::3]
работает преобразовать его из списка в строку? Я никогда не видел этого раньше.[
.[1::3]
получает символ с индексом 1, затем каждый третий. Ибо[1, 2, 3]
, что дает123
, пропуская скобки, запятые и пробелы.[1, 2, 3]
это уже было зачеркнуто и что запятые и пробелы нужно пропускать. Благодарность!Брахилог ,
910 байтПопробуйте онлайн!
Как обычно для Brachylog, это функция представления. Приведенная выше ссылка на TIO получила аргумент командной строки для превращения функции в полноценную программу.
Мне пришлось добавить дополнительный байт из первой версии этого, меняя
ℕ
наℕ₁
, чтобы запретить вывод 0 (кое-что, что теперь было разъяснено).объяснение
Довольно неэффективно, потому что интерпретатор генерирует список всех возможных значений, а затем выбирает одно случайным образом (вот что
ᶠṛ
означает; у Brachylog не было опции «выбрать случайное решение» во время, когда был задан этот вопрос).Некоторые комментарии по поводу маркировки здесь: если
≜
опущен, раздел в фигурных скобках создает только одно значение, ограничение, представляющее числа с свойством; поэтому выбор случайного результата дает нам ограничение, и интерпретатор выводит минимальное абсолютное значение, которое удовлетворяет ограничению (1, 10, 102, 1023, 10234 и т. д.), а это не то, что нам нужно. Таким образом, мы должны заставить его создать список с помощью явной маркировки.Большинство реализаций Пролога, которые я видел, имеют встроенную функцию для поиска случайного результата, соответствующего ограничению, но обычно не с одинаковой вероятностью; Однако у Brachylog такого не было (один был добавлен в ответ на этот вызов, но, очевидно, я не могу использовать его из-за правил лазейки). Если это произойдет, и если это произойдет, чтобы дать равномерную вероятность этой проблемы, эта программа будет просто
~lℕ₁≠
следовать за этой встроенной, для вероятной длины 6 байтов.Brachylog , 8 байт, в сотрудничестве с @Fatalize
Попробуйте онлайн!
Это своего рода гениальный трюк низкого уровня, который имеет смысл только с тем, как Пролог делает вещи, и не имеет особого смысла при математическом описании.
Как и раньше,
~lℕ₁≠
создается значение, описывающее ограничение («длина равна входному значению, натуральное число, все элементы разные»). Затем≜ᶠ
генерирует все возможные значения, которые соответствуют ограничению. Дело в том, что с оценочной последовательностью Brachylog, пока не≜
появится фактический выбор, операции «найти все решения» неᶠ
должны применяться ни к чему, кроме операции «конкретное значение, которое выполняет ограничение»≜
. Это означает, что нет необходимости{…}
выбирать область видимости, экономя 2 байта.источник
≜₁
прежде чем понял, что оно было добавлено из-за этой проблемыЖеле , 9 байт
Попробуйте онлайн! (не будет работать в TIO для n> 6 из-за неэффективности реализации)
или альтернативная реализация того же самого:
Как?
Это довольно подлый и очень неэффективный! Jelly делает некоторые полезные вещи неявно, когда атом ожидает список, но получает целое число (это разработано).
Этот код использует пару из этих полезных неявных действий:
Монадический атом
Ṗ
«pop», когда вызывается с целочисленным вводом, неявно создает диапазон, из которого нужно выскочить, так что ввод n сначала делает [1, 2, ..., n] , а затем выскакивает, приводя к [1, 2 , ..., n-1] .Монадический атом
Q
, «дедупликация» или «уникальный», при вызове с целочисленным вводом неявно создает десятичный список для дедупликации, поэтому ввод n, где:n = d k-1 × 10 k-1 + d k-2 × 10 k-2 + ... + d 1 × 10 + d 0
сначала делает
[d k-1 , d k-2 , ..., d 1 , d 0 ],
а затем выдает уникальные значения Первое появление.
Так, например, n = 5835518 даст [5, 8, 3, 1] .
Кроме того, монадический атом
M
, «максимальные индексы элементов», возвращает индексы максимальных элементов из списка, это экономит два байта по сравнению с гораздо более очевидной альтернативой проверки на равенство с вводом и нахождения истинных индексов⁵*ṖQL$€=⁸TX
, или⁵*ṖðQL⁼ð€TX
Все это довольно неэффективно, как по времени, так и по памяти: сначала создается список из 10 n целых чисел, а одно отбрасывается, затем для каждого из них создается список из n целых чисел (а не какой-то причудливый 4-битный объект или перечисление) а затем дедуплицируется. Эта дедупликация имеет полностью основанную на списке реализацию (никакие наборы, отсортированные наборы или словари не задействуются под капотом, каждая цифра проверяется на наличие в списке, который в конечном итоге получает выходные данные).
В автономном режиме n = 7 использует ~ 0,5 ГБ и занимает ~ 25 секунд, в то время как n = 8 использует ~ 4 ГБ и занимает ~ 5 минут - я не потрудился запустить n = 9 как у меня только 16 ГБ ОЗУ (я думаю, это займет ~ 45 минут ).
Альтернативная реализация просто использует встроенный
ÐṀ
быстрый фильтр, чтобы минимизировать фильтрацию (который здесь просто добавляет небольшие издержки в управлении для того же количества байтов).источник
Желе , 11 байт
Попробуйте онлайн!
Как это работает
источник
JavaScript (ES6),
72717069 байтЭто рекурсивная функция, которая принимает количество цифр х . Второй параметр y , изначально установленный в пустую строку, отслеживает число, поскольку мы генерируем его цифра за цифрой.
Сначала мы генерируем случайную цифру z с
Math.random()*10|0
. Теперь мы хотим проверить, что y не содержит z , а y и z не равны 0 .Мы можем вычислить первое условие с
!y.match(z)
.y.match(z)
возвращает массив (всегда правдивый), если y содержит z , в противном случае - null (false);!
преобразует это логическое и инвертирует его.Второе условие проверяется с
y|z
. Хотя y - строка, JS неявно преобразует ее в целое число при использовании|
. Это положительное целое число, если у уже есть цифры, 0 в противном случае. Чистый результат состоит в том, чтоy|z
возвращает 0, если y пусто и z равно 0 , или положительное целое число в противном случае.Если оба эти условия выполняются, тогда мы добавляем цифру к y , уменьшаем x и начинаем процесс заново. В противном случае мы просто возвращаемся к началу и надеемся, что следующая случайная цифра сработает. Когда x достигает 0 , мы просто возвращаем пустую строку, чтобы завершить рекурсию.
Предыдущая версия:
Это рекурсивная функция, которая принимает количество цифр. Первоначально неопределенный второй параметр, y , представляет собой 10-битную справочную таблицу, сообщающую нам, какие цифры у нас уже есть, которые удобно хранить в виде целого числа.
Сначала мы генерируем случайную цифру z с
Math.random()*10|0
. Теперь мы хотим проверить, что младший значащий бит z для y не установлен, и что y и z не равны 0 .Мы можем вычислить первое условие с помощью
~y>>z&1
; инвертировать y , сдвинуть его на z бит вправо и взять только младший бит. Это дает 1, если мы еще не сгенерировали соответствующую цифру, или 0 в противном случае.Второе условие поначалу было довольно сложно выяснить (
y/z
сначала я попытался сгенерировать,NaN
если они оба равны 0), но в какой-то момент я понял, что это простоy|z
поможет. Результат равен 0 тогда и только тогда, когда y и z равны 0 ; в противном случае положительное целое число.Если оба эти условия истинны (
~y>>z&1&&y|z
), то мы генерируем оставшуюся часть числа и добавляем z . Остальная часть числа генерируется путем повторного вызова функции с помощьюx-1
иy|1<<z
( y , но с битом с индексом z, установленным в 1 ). Когда x достигает 0 , мы просто возвращаем пустую строку, чтобы завершить рекурсию.источник
ClojureScript,
8179 байтЭто анонимная функция, поэтому вы должны использовать ее следующим образом:
Где вы заменяете
{arguments}
ваши аргументы.Вы можете попробовать код здесь (ClojureScript REPL).
Спасибо,
@cliffroot
что сбрил 2 байта!Расширенный код:
Объяснение:
Я собираюсь пройти строки по очереди, используя пример ввода
8
.Довольно просто, это определяет функцию
random-digits
с одним вызываемым аргументомn
. В своем ответе я использовал анонимную функцию (#(...)
), чтобы сохранить байты.Давайте рассмотрим внутри
let
, изнутри:В ClojureScript (и Clojure)
(range n)
похож на Pythonrange(n)
: он дает вам список с каждым числом от0
доn - 1
(9
в данном случае).shuffle
берет список и возвращает вектор (который немного отличается от списка) со всеми перемешанными элементами. Итак, используя наш пример, мы получаем что-то вроде этого:(subvec vector start end)
принимает вектор (только вектор) и возвращает вектор со всеми элементами из индексаstart
вend
. В этом случае мы берем элементы из0
элемента th в аргумент, данныйrandom-digits
. Если мы применим это к нашему примеру, мы получим:Это
if
заявление проверяет , является ли первый элементnum-vector
является0
.Если это так
0
, то мы снова вызываем функцию с аргументомn
, используяrecur
.Если это не так
0
:(apply function list)
берет список и плюет их в функцию в качестве аргументов. Например:Превращается в:
Который равен
9
.(str items)
превращает каждый элемент вitems
строку, а затем объединяет их.int
преобразует что-либо в целое число. Поэтому, если мы применим это к нашему примеру, мы получим:Какой наш окончательный ответ.
источник
(int string)
вместо(Integer/parseInt string)
:)read-string
в Clojure, но это не намного лучше ...#(let[a(subvec(shuffle(range 10))0 %)](if(=(a 0)0)(recur %)(int(apply str a))))
перемещаетapply str
часть в конец, позволяет сравнивать0
вместо,\0
а использоватьsubvec
вместоtake
позволяет использовать вектор как функцию и, таким образом, удалятьfirst
shuffle
превратил коллекцию вvec
. Благодарность!Python 2,
898180 байтПопробуйте онлайн
источник
99**n
, просто чтобы убедиться, что я их всех получу. : Dif`set(`i`)`[5*n:]]
.R, 45 байт
источник
k=0
так как это неявный вектор длины один, и вы можете использовать i = scan (), чтобы получить входные данные из stdin в качестве числа. Я также не уверен, что список цифр - это «правильное» представление, но я не судья.while(!k[1])
работать, чтобы сохранить 2 байта?Утилиты Bash + GNU, 46
Попробуйте онлайн .
Это занимает много времени для больших n - около 30 с для n = 7 и увеличивается в 10 раз для каждого приращения, поэтому, вероятно, 8-9 часов для n = 10.
источник
Java 7,
150147145134 байта-2 байта благодаря @TheLethalCoder
(старый) Объяснение:
Тестовый код:
Попробуй это здесь.
Пример вывода:
источник
n->...
или это Java 8+?for(int l,x;(l=r.length())<n;)
вы должны сохранить байт.n->...
это Java 8. Лично я предпочитаю codegolf в Java 7, хотя 8 всегда короче.Perl 6 , 44 байта
Попытайся
Expanded:
источник
PHP, 67 байт
Онлайн версия
Все версии основаны на перемешивании цифр от 0 до 9
71 байт
73 байта
источник
MATL , 15 байт
Попробуйте это в MATL Online!
объяснение
источник
Желе , 12 байт
В настоящее время один байт позади моего другого ответа Желе, но мне действительно нравится этот.
Попробуйте онлайн!
Как это работает
источник
АПЛ (Дьялог) ,
271917 байтовТребуется
⎕IO←0
по умолчанию во многих системах.Попробуйте онлайн!
Перемешивает цифры до действительного:
10⊥
расшифровывать от 10 цифр до обычного номера,⊢
тогда↑
первые элементы{
...}⍣{
...}
повторяя функцию ...?⍨10
перетасовать первые десять положительных целые числа ,пока ...
⊃⍺
первая цифра последней попытки×
не является положительнойисточник
Питон 2 ,
100939290 байтСпасибо @ mbomb007 за то, что сбрил 2 байта
Пытается набрать нужные номера, пока не будет найдено однозначное число. Могу поспорить, есть намного более чистый способ сделать это, но ни один не приходит на ум.
источник
return(n==len(set(`k`)))*k or f(n)
, Попробуйте онлайнPyth , 11 байт
Использует тот же алгоритм, что и ответ Денниса .
Попробуйте онлайн!
источник
Perl, 48 байт
Объяснение:
Повторно генерируйте случайные целые числа от 1 до 10 ** $ n-1, отклоняя их до тех пор, пока не будет найдена одна из правильных длин (поэтому не менее 10 ** ($ n-1)) без повторяющихся цифр.
источник
Пакетный, 156 байт
x
поддерживает битовую маску используемых цифр.f
указывает количество доступных цифр (начиная с 9). Случайные цифры генерируются до тех пор, пока не будет найдена неиспользуемая цифра.n=10
может поддерживаться на 165 байтов:(
r
содержит дополнительный начальный ноль, потому что в этом случае он более гольфистский.) Предыдущий подход для 165 байтов специально обрабатывал первую цифру и также работал сn=10
(числовая версия фактически занимала 166 байтов!)Оригинальный подход для 170 байтов также работал для
n=10
:Использует манипуляции со строками для обнаружения повторяющихся цифр.
источник
Баш , 66 байт
Попробуйте онлайн!
Прямо вперед, использует shuf, xargs используется для объединения строк и продолжает попытки, пока комбинация начинается с 0.
Не могу победить 46 символов из другого ответа, но так быстро!
источник
Pyth,
1528 байтПопробуй здесь
источник
0
, поэтому я думаю, что вы захотите изменить^TttQ
на^TtQ
(-1 байт, бонус!). 2) все цифры в выводе должны быть уникальными, так что вам придется как-то заставить это произойти.C #,
127132128126125 байтовПопробуйте онлайн!
Заимствовал идею из ответа @ KevinCruijssen об инициализации случайного
r
, вif
выражении для сохранения 2 байтов.Я уверен, что это может быть дальше, но у меня нет времени на данный момент.
Старая версия с использованием
while
цикла:источник
0
сначала оно попытается установить значение «if(s.Length<1&r>0)
ложь», но затем оно выполнит значение «if(!s.Contains(r+""))
истина» и все равно будет добавлено"0"
вs
качестве первой цифры..Next(10)
... с;
. Так что никаких дальнейших улучшений нет, но хорошая идея.n=>{var s="";for(int l=0,r;l<n;l=s.Length)if((l<1&(r=new System.Random().Next(10))>0)|(l>0&!s.Contains(r+"")))r+=x;return s;};
C (gcc) ,
123122100951041039997 байтЭтот генерирует фактическое случайное число
Попробуйте онлайн!
C (gcc) ,
8785 байтЗдесь он печатает строку цифр.
Попробуйте онлайн!
источник
PHP,
6563 байтапринимает данные от STDIN; бежать с
-nR
.создать случайное число между
1
и10^N
включительно;Повторите, пока количество различных символов <
N
.источник
while(count(count_chars($x=rand(1,10**$argn),1))<$argn);echo$x;
-2 байтаMathematica
6560 байтВот более быстрая версия, но добавляет 9 байтов:
источник
Java 9 JShell, 86 байт
Попробуйте онлайн!
Примечание: я не считаю импорт, поскольку эти пакеты импортируются по умолчанию в JShell, но для JShell я не знаю ссылки Try-it-online, поэтому я предоставил одну для Java 9 с кодом верхнего и нижнего колонтитула для заставить это работать в этом контексте. В JShell вы можете просто сделать:
А потом:
Как это работает:
Мы определяем функцию от Integer до Long и создаем бесконечный поток случайных длин в диапазоне от 0-9, ограничиваем ее первыми n-1 элементами, затем уменьшаем ее со случайным int от 1-9 в качестве начального значения и функция, которая умножает значение на 10 и добавляет следующее значение из потока.
Я использовал longs, так что это должно работать примерно до 18 цифр (n = 18).
источник
C
9693 байтаИнициализация Фишера-Йейтса до тех пор, пока первая цифра не станет нулевой.
Равномерно, предполагая
rand()%i
равномерно. (Так как для большинства яRAND_MAX/i
оставляю небольшой остаток, существует очень маленький уклон. Этот уклон уменьшается с ростом RAND_MAX.)Посмотрите, как работает онлайн .
Смотрите, генерируйте правильные числа, когда n равно 2, как показано в вопросе .
источник
Аксиома, 191 байт
Развернись, результат теста
источник
Медуза , 17 байт
Попробуйте онлайн!
Вилка Дениса Желе ответ .
источник
Рубин,
5352 байтаПеремешайте, пока первая цифра не станет 0, затем объедините цифры и преобразуйте в целое число.
Попробуйте онлайн!
источник