Получить случайное число из n цифр с разными цифрами и сначала не 0


22

Я прочитал этот вопрос и подумал, что это будет хорошим испытанием.

задача

Дайте вход 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 

4
Требовать случайности без указания распределения следует избегать.
flawr

вернуть как целое число, а не строку, да?
Джузеппе

@Giuseppe генерирует случайное число
mbomb007

4
Я думаю об этом каждый раз, когда кто-то задает
Thunda

1
@ ais523 «Дайте вход 0 <n <10, сгенерируйте случайное число с помощью»
cleblanc

Ответы:


17

Python 2 , 77 байт

from random import*
r=range(10)
while[1]>r:shuffle(r)
print`r`[1:input()*3:3]

Попробуйте онлайн!

Перемешивает список из 10 цифр до тех пор, пока он не начинается с 0, а затем создает число с указанными первыми nцифрами.


Определенно работает быстрее и с меньшим объемом памяти для ввода 9или 10.
mbomb007

Аккуратное решение! Не могли бы вы объяснить, как [1::3]работает преобразовать его из списка в строку? Я никогда не видел этого раньше.
Джулиан Вольф

@JulianWolf Это работает, только если каждый элемент списка имеет одинаковую длину. На самом деле он принимает строковое представление списка, а затем разрезает его, принимая каждый третий символ после пропуска первого [.
mbomb007

@JulianWolf [1::3]получает символ с индексом 1, затем каждый третий. Ибо [1, 2, 3], что дает 123, пропуская скобки, запятые и пробелы.
Деннис

Стреляй, ладно - это имеет смысл. Я забыл, что [1, 2, 3]это уже было зачеркнуто и что запятые и пробелы нужно пропускать. Благодарность!
Джулиан Вольф

10

Брахилог , 9 10 байт

{~lℕ₁≜≠}ᶠṛ

Попробуйте онлайн!

Как обычно для Brachylog, это функция представления. Приведенная выше ссылка на TIO получила аргумент командной строки для превращения функции в полноценную программу.

Мне пришлось добавить дополнительный байт из первой версии этого, меняя на ℕ₁, чтобы запретить вывод 0 (кое-что, что теперь было разъяснено).

объяснение

{~lℕ₁≜≠}ᶠṛ
{      }ᶠṛ  Pick a random value with these properties:
 ~l           it has length equal to the input;
   ℕ₁         it's a positive integer;
     ≜        it's a specific value (not a constraint);
      ≠       all its elements (digits in this case) are different.

Довольно неэффективно, потому что интерпретатор генерирует список всех возможных значений, а затем выбирает одно случайным образом (вот что ᶠṛ означает; у Brachylog не было опции «выбрать случайное решение» во время, когда был задан этот вопрос).

Некоторые комментарии по поводу маркировки здесь: если опущен, раздел в фигурных скобках создает только одно значение, ограничение, представляющее числа с свойством; поэтому выбор случайного результата дает нам ограничение, и интерпретатор выводит минимальное абсолютное значение, которое удовлетворяет ограничению (1, 10, 102, 1023, 10234 и т. д.), а это не то, что нам нужно. Таким образом, мы должны заставить его создать список с помощью явной маркировки.

Большинство реализаций Пролога, которые я видел, имеют встроенную функцию для поиска случайного результата, соответствующего ограничению, но обычно не с одинаковой вероятностью; Однако у Brachylog такого не было (один был добавлен в ответ на этот вызов, но, очевидно, я не могу использовать его из-за правил лазейки). Если это произойдет, и если это произойдет, чтобы дать равномерную вероятность этой проблемы, эта программа будет просто ~lℕ₁≠следовать за этой встроенной, для вероятной длины 6 байтов.

Brachylog , 8 байт, в сотрудничестве с @Fatalize

~lℕ₁≠≜ᶠṛ

Попробуйте онлайн!

Это своего рода гениальный трюк низкого уровня, который имеет смысл только с тем, как Пролог делает вещи, и не имеет особого смысла при математическом описании.

Как и раньше, ~lℕ₁≠создается значение, описывающее ограничение («длина равна входному значению, натуральное число, все элементы разные»). Затем ≜ᶠгенерирует все возможные значения, которые соответствуют ограничению. Дело в том, что с оценочной последовательностью Brachylog, пока не появится фактический выбор, операции «найти все решения» не должны применяться ни к чему, кроме операции «конкретное значение, которое выполняет ограничение» . Это означает, что нет необходимости {…}выбирать область видимости, экономя 2 байта.


Я собирался опубликовать решение, ≜₁прежде чем понял, что оно было добавлено из-за этой проблемы
Несвязанная строка

8

Желе , 9 байт

⁵*ṖQL$€MX

Попробуйте онлайн! (не будет работать в TIO для n> 6 из-за неэффективности реализации)

или альтернативная реализация того же самого:

⁵*ṖQL$ÐṀX

Как?

Это довольно подлый и очень неэффективный! 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

⁵*ṖQL$€MX - Main link: n                       e.g. 2
⁵         - literal 10
 *        - exponentiate: 10^n                      100
  Ṗ       - pop (make range 1 to 10^n, then pop)    [1  ,2  ,...,21   ,22 ,23   ,...,97   ,98   ,99]
     $€   - last two links as a monad for €ach:
   Q      -   unique (makes a decimal list first)   [[1],[2],...,[2,1],[2],[2,3],...,[9,7],[9,8],[9]]
    L     -   length                                [1  ,1  ,...,2    ,1  ,2    ,...,2    ,2    ,1  ]
       M  - indexes of maximal elements             [        ...,21       ,23,   ...,97   ,98       ]
          -                                         - i.e. all n-digit numbers with n-distinct digits.
        X - pick a random element from that list

Все это довольно неэффективно, как по времени, так и по памяти: сначала создается список из 10 n целых чисел, а одно отбрасывается, затем для каждого из них создается список из n целых чисел (а не какой-то причудливый 4-битный объект или перечисление) а затем дедуплицируется. Эта дедупликация имеет полностью основанную на списке реализацию (никакие наборы, отсортированные наборы или словари не задействуются под капотом, каждая цифра проверяется на наличие в списке, который в конечном итоге получает выходные данные).
В автономном режиме n = 7 использует ~ 0,5 ГБ и занимает ~ 25 секунд, в то время как n = 8 использует ~ 4 ГБ и занимает ~ 5 минут - я не потрудился запустить n = 9 как у меня только 16 ГБ ОЗУ (я думаю, это займет ~ 45 минут ).

Альтернативная реализация просто использует встроенный ÐṀбыстрый фильтр, чтобы минимизировать фильтрацию (который здесь просто добавляет небольшие издержки в управлении для того же количества байтов).


Ух ты. Я пытался сделать что-то очень похожее на это, но упустил хитрость, заключающуюся в хранении значений для возврата в индексах списка (путем подходящего заполнения списка), вместо того, чтобы пытаться хранить их отдельно. Это трюк, который довольно часто используется в Jelly, и я, кажется, всегда скучаю по нему.

7

Желе , 11 байт

9Xœ|⁵ḶẊ¤ḣ¹Ḍ

Попробуйте онлайн!

Как это работает

9Xœ|⁵ḶẊ¤ḣ¹Ḍ  Main link. Argument: n

9            Set the return value to 9.
 X           Pick; pseudo-randomly select an integer from [1, ..., 9].
       ¤     Combine the three preceding links into a niladic chain.
    ⁵          Yield 10.
     Ḷ         Unlength; yield [0, ..., 9].
      Ẋ        Shuffle; pseudo-randomly select a permutation of [0, ..., 9].
  œ|         Multiset OR; prepend the selected integer to the selected permutation
             and remove the second occurrence of the first element.
         ¹   Identity; yield n.
        ḣ    Head; keep the first n digits of the permutation.
          Ḍ  Undecimal; convert from base 10 to integer.

Это очень умный способ удалить дубликаты ...
Leaky Nun,

7

JavaScript (ES6), 72 71 70 69 байт

f=(x,y="")=>x?!y.match(z=Math.random()*10|0)&&y|z?f(x-1,y+z):f(x,y):y

Это рекурсивная функция, которая принимает количество цифр х . Второй параметр 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 , мы просто возвращаем пустую строку, чтобы завершить рекурсию.


Предыдущая версия:

f=(x,y)=>x?~y>>(z=Math.random()*10|0)&1&&y|z?z+f(x-1,y|1<<z):f(x,y):""

Это рекурсивная функция, которая принимает количество цифр. Первоначально неопределенный второй параметр, 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 , мы просто возвращаем пустую строку, чтобы завершить рекурсию.


5

ClojureScript, 81 79 байт

#(let[a(subvec(shuffle(range 10))0 %)](if(=(a 0)0)(recur %)(int(apply str a))))

Это анонимная функция, поэтому вы должны использовать ее следующим образом:

(#(...) {arguments})

Где вы заменяете {arguments}ваши аргументы.

Вы можете попробовать код здесь (ClojureScript REPL).

Спасибо, @cliffrootчто сбрил 2 байта!


Расширенный код:

(defn random-digits [n]
  (let [num-vector
        (subvec
          (shuffle (range 10))
          0 n)]
    (if (= (num-vector 0) 0)
      (recur n)
      (int (apply str num-vector)))))

Объяснение:

Я собираюсь пройти строки по очереди, используя пример ввода 8.


(defn random-digits [n] ...)

Довольно просто, это определяет функцию random-digitsс одним вызываемым аргументом n. В своем ответе я использовал анонимную функцию ( #(...)), чтобы сохранить байты.


(let [num-vector ...] ...)

Давайте рассмотрим внутри let, изнутри:

(shuffle (range 10))

В ClojureScript (и Clojure) (range n)похож на Python range(n): он дает вам список с каждым числом от 0до n - 1(9 в данном случае).

shuffleберет список и возвращает вектор (который немного отличается от списка) со всеми перемешанными элементами. Итак, используя наш пример, мы получаем что-то вроде этого:

[1 0 8 3 6 7 9 2 4 5]

(subvec {see above} 0 n)

(subvec vector start end)принимает вектор (только вектор) и возвращает вектор со всеми элементами из индекса startв end. В этом случае мы берем элементы из 0элемента th в аргумент, данный random-digits. Если мы применим это к нашему примеру, мы получим:

[1 0 8 3 6 7 9 2]

(if (= (num-vector 0) 0)
  (recur n)
  (int (apply str num-vector)))

Это ifзаявление проверяет , является ли первый элемент num-vectorявляется 0.

Если это так 0, то мы снова вызываем функцию с аргументом n, используя recur.

Если это не так 0:


(int (apply str num-vector))

(apply function list)берет список и плюет их в функцию в качестве аргументов. Например:

(apply + [2 3 4])

Превращается в:

(+ 2 3 4)

Который равен 9.

(str items)превращает каждый элемент в itemsстроку, а затем объединяет их. intпреобразует что-либо в целое число. Поэтому, если мы применим это к нашему примеру, мы получим:

   (int (apply str [1 0 8 3 6 7 9 2]))
=> (int (str 1 0 8 3 6 7 9 2))
=> (int "10836792")
=> 10836792

Какой наш окончательный ответ.


2
Должен любить ClojureScript за разрешение (int string)вместо (Integer/parseInt string):)
Cliffroot

1
@cliffroot Я имею в виду, вы можете сделать это read-stringв Clojure, но это не намного лучше ...
clismique

Сохранение 2 байтов #(let[a(subvec(shuffle(range 10))0 %)](if(=(a 0)0)(recur %)(int(apply str a))))перемещает apply strчасть в конец, позволяет сравнивать 0вместо, \0а использовать subvecвместо takeпозволяет использовать вектор как функцию и, таким образом, удалятьfirst
cliffroot

@cliffroot Да, не знал, что shuffleпревратил коллекцию в vec. Благодарность!
Придется

5

Python 2, 89 81 80 байт

from random import*
lambda n:choice([i for i in range(10**n)if`set(`i`)`[5*n:]])

Попробуйте онлайн


Я не думаю, что вам нужно начальное значение для диапазона.
Деннис

Ницца! Это замедлит это. : D Жаль, что я не могу использовать генератор вместо списка.
mbomb007

Только на 11%. Загляните в ведро для кода гольф.
Деннис

Да, я должен использовать 99**n, просто чтобы убедиться, что я их всех получу. : D
mbomb007

Я тоже смотрел на это, но получил 80, используя if`set(`i`)`[5*n:]].
Джонатан Аллан

5

R, 45 байт

k=0
i=scan()
while(!k[1])k=sample(0:9)[1:i]
k

Я думаю, вы можете просто установить, k=0так как это неявный вектор длины один, и вы можете использовать i = scan (), чтобы получить входные данные из stdin в качестве числа. Я также не уверен, что список цифр - это «правильное» представление, но я не судья.
Джузеппе

@Giuseppe Спасибо за ввод, обновил оба ваших предложения (на обоих постах), спасибо.
Нил

Будет ли while(!k[1])работать, чтобы сохранить 2 байта?
BLT

@BLT Обновлено, спасибо.
Нил

3

Утилиты Bash + GNU, 46

seq 1e$[$1-1] 1e$1|egrep -v '(.).*\1'|shuf -n1

Попробуйте онлайн .

Это занимает много времени для больших n - около 30 с для n = 7 и увеличивается в 10 раз для каждого приращения, поэтому, вероятно, 8-9 часов для n = 10.


на вопрос, n = 10 не нужно даже работать, а тем более быть быстрым
ysth

3

Java 7, 150 147 145 134 байта

String c(int n){String r="";for(int l,x;(l=r.length())<n;)if(l<1&(x=(int)(Math.random()*10))>0|(l>0&!r.contains(""+x)))r+=x;return r;}

-2 байта благодаря @TheLethalCoder

(старый) Объяснение:

String c(int n){                           // Method with integer parameter and String return-type
  String r="";                             //  Result-String
  for(int l=0,x;l<n;l=r.length()){         //  Loop until the length of the result-String is equal to the parameter integer
    x=new java.util.Random().nextInt(10);  //   Random digit
    if((l<1&x>0)                           //   If the length is zero and the random digit is not zero
       |(l>0&!r.contains(""+x)))           //     or the length is at least 1, and the result-String does not contain this random digit yet
      r+=x;                                //    Append the random digit to the result-String
  }                                        //  End of for-loop
  return r;                                //  Return result-String
}                                          // End of method

Тестовый код:

Попробуй это здесь.

class M{
  String c(int n){String r="";for(int l,x;(l=r.length())<n;)if(l<1&(x=(int)(Math.random()*10))>0|(l>0&!r.contains(""+x)))r+=x;return r;}

  public static void main(String[] a){
    M m = new M();
    System.out.println(m.c(4));
    System.out.println(m.c(10));
  }
}

Пример вывода:

7194
8672953041

Вы не можете использовать лямбда-выражение здесь? т.е. n->...или это Java 8+?
TheLethalCoder

1
Вы также можете позаимствовать уловку, которую я только что использовал в своем ответе, установить длину в проверке сравнения, т.е. for(int l,x;(l=r.length())<n;)вы должны сохранить байт.
TheLethalCoder

1
@TheLethalCoder А, конечно, спасибо. Отличная командная работа! ;) И да, n->...это Java 8. Лично я предпочитаю codegolf в Java 7, хотя 8 всегда короче.
Кевин Круйссен

2

Perl 6 , 44 байта

{(->{+[~] (^10).pick($_)}...*>9 x$_-1).tail}

Попытайся

Expanded:

{  # bare block with implicit parameter 「$_」
  (

    ->{  # pointy block lambda with no parameters

      +                # turn the following into a numeric
      [~]              # concatenate the following

        (^10).pick($_) # grab $_ digits at random from 0..9
    }

    ...                # keep doing that until

    * > 9 x $_-1       # one of them is big enough

  ).tail # return the last one (only valid one)
}

2

PHP, 67 байт

Онлайн версия

Все версии основаны на перемешивании цифр от 0 до 9

for($a=range(0,9);!$a[0];)shuffle($a);for(;$i<$argn;)echo$a[+$i++];

71 байт

for($s="0123456789";!$s[0];)$s=str_shuffle($s);echo substr($s,0,$argn);

73 байта

for($a=range(0,9);!$a[0];)shuffle($a);echo join(array_slice($a,0,$argn));

2

MATL , 15 байт

`4Y2GZr1)48=]8M

Попробуйте это в MATL Online!

объяснение

`        % Do...while
  4Y2    %   Push predefined literal '0123456789'
  G      %   Push input n
  Zr     %   Random sample of n unique characters from that string
  1)     %   Pick the first
  48=    %   Is it 48? This is the loop condition
]        % End. If top of the stack evaluates to true: next iteration
8M       % Push the latest random sample. Implicitly display

2

Желе , 12 байт

9×!X+!Œ?’ḣƓḌ

В настоящее время один байт позади моего другого ответа Желе, но мне действительно нравится этот.

Попробуйте онлайн!

Как это работает

9×!X+!Œ?’ḣƓḌ  Main link. No arguments.

9             Set the argument and the return value to 9.
  !           Yield 9!
 ×            Compute 9 × 9!.
   X          Pick; pseudo-randomly select an integer j from [1, ..., 9 × 9!].
     !        Yield 9!
    +         Compute k := j + 9!.
              The result will belong to [9! + 1, 10!].
      Œ?      Get the permutation P of R := [1, ..., r], with minimal r, such that
              P is the lexicographically k-th permutation of R.
              Since k belongs to [9! + 1, 10!], r = 10 and this generates a per-
              mutation between [2,1,3,4,5,6,7,8,9,10] and [10,9,8,7,6,5,4,3,2,1].
        ’     Subtract 1 from all integers in P.
          Ɠ   Read an integer n from STDIN and yield it.
         ḣ    Head; keep the first n digits of the permutation.
           Ḍ  Undecimal; convert from base 10 to integer.

2

АПЛ (Дьялог) , 27 19 17 байтов

Требуется ⎕IO←0по умолчанию во многих системах.

10⊥⊢↑{?⍨10}⍣{×⊃⍺}

Попробуйте онлайн!

Перемешивает цифры до действительного:

10⊥ расшифровывать от 10 цифр до обычного номера,

 тогда

 первые элементы

{... }⍣{... } повторяя функцию ...
?⍨10 перетасовать первые десять положительных целые числа ,
пока ...
⊃⍺ первая цифра последней попытки
× не является положительной


1

Питон 2 , 100 93 92 90 байт

Спасибо @ mbomb007 за то, что сбрил 2 байта

from random import*
def f(n):k=randint(10**~-n,10**n-1);return(n==len(set(`k`)))*k or f(n)

Пытается набрать нужные номера, пока не будет найдено однозначное число. Могу поспорить, есть намного более чистый способ сделать это, но ни один не приходит на ум.


return(n==len(set(`k`)))*k or f(n), Попробуйте онлайн
mbomb007


1

Perl, 48 байт

1until$_=1+int rand 10**$n-1,/.{$n}/&&!/(.).*\1/

Объяснение:

Повторно генерируйте случайные целые числа от 1 до 10 ** $ n-1, отклоняя их до тех пор, пока не будет найдена одна из правильных длин (поэтому не менее 10 ** ($ n-1)) без повторяющихся цифр.


1

Пакетный, 156 байт

@set/af=9,r=x=0
@for /l %%i in (1,1,%1)do @call:c
@echo %r%
@exit/b
:c
@set/a"d=9-%random%%%f,e=x>>d&1
@if %e%==1 goto c
@set/a"r=r*10+d,f=10,x|=1<<d

xподдерживает битовую маску используемых цифр. fуказывает количество доступных цифр (начиная с 9). Случайные цифры генерируются до тех пор, пока не будет найдена неиспользуемая цифра. n=10может поддерживаться на 165 байтов:

@set/af=9,r=x=0
@for /l %%i in (1,1,%1)do @call:c
@echo %r:~1%
@exit/b
:c
@set/a"d=9-%random%%%f,e=x>>d&1
@if %e%==1 goto c
@set r=%r%%d%
@set/a"f=10,x|=1<<d

( rсодержит дополнительный начальный ноль, потому что в этом случае он более гольфистский.) Предыдущий подход для 165 байтов специально обрабатывал первую цифру и также работал с n=10(числовая версия фактически занимала 166 байтов!)

@set/ar=%random%%%9+1,x=0
@for /l %%i in (2,1,%1)do @set/a"x|=1<<d"&call:c
@echo %r%
@exit/b
:c
@set/a"d=%random%%%10,e=x>>d&1
@if %e%==1 goto c
@set r=%r%%d%

Оригинальный подход для 170 байтов также работал для n=10:

@set/ar=%random%%%9+1
@for /l %%i in (2,1,%1)do @call:c
@echo %r%
@exit/b
:c
@set/ad=%random%%%10
@call set s=%%r:%d%=%%
@if not "%s%"=="%r%" goto c
@set r=%r%%d%

Использует манипуляции со строками для обнаружения повторяющихся цифр.


1

Баш , 66 байт

a=0;while [[ $a == 0* ]];do a=`shuf -i0-9 -n$1|xargs`;done;echo $a

Попробуйте онлайн!

Прямо вперед, использует shuf, xargs используется для объединения строк и продолжает попытки, пока комбинация начинается с 0.

Не могу победить 46 символов из другого ответа, но так быстро!


1

Pyth, 15 28 байт

=+YhO9VtQ#KOTI!hxYK=+YKB;jkY

Попробуй здесь


1
Добро пожаловать в PPCG, и отличная работа с использованием языка игры в гольф сразу :-) Я вижу 2 маленьких проблемы: 1) кажется, что вторая цифра всегда 0, поэтому я думаю, что вы захотите изменить ^TttQна ^TtQ(-1 байт, бонус!). 2) все цифры в выводе должны быть уникальными, так что вам придется как-то заставить это произойти.
ETHproductions

@ETHproductions Arg !! Спасибо что подметил это. Я исправил это.
Мария

1

C #, 127 132 128 126 125 байтов

n=>{var s="";for(int l,r;(l=s.Length)<n;)if((l<1&(r=new System.Random().Next(10))>0)|(l>0&!s.Contains(r+"")))s+=r;return s;};

Попробуйте онлайн!

Заимствовал идею из ответа @ KevinCruijssen об инициализации случайного r, вif выражении для сохранения 2 байтов.

Я уверен, что это может быть дальше, но у меня нет времени на данный момент.


Старая версия с использованием while цикла:

n=>{var s="";while(s.Length<n){int r=new System.Random().Next(10);if(s.Length<1&r>0)s+=r;else if(!s.Contains(r+""))s+=r;}return s;};

Я не думаю, что это правильно. Скажем, первое случайное целое число: 0сначала оно попытается установить значение « if(s.Length<1&r>0)ложь», но затем оно выполнит значение « if(!s.Contains(r+""))истина» и все равно будет добавлено "0"в sкачестве первой цифры.
Кевин Круйссен

@KevinCruijssen Исправлена ​​и игра в гольф дальше
TheLethalCoder

1
@KevinCruijssen А, я решил, в вашем примере вы не заканчиваете .Next(10)... с ;. Так что никаких дальнейших улучшений нет, но хорошая идея.
TheLethalCoder

1
Я только что опубликовал это. И, к сожалению, вы правы, я пропустил эту 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;};
точку с

1
@KevinCruijssen Я просто позаимствовал идею из твоего ответа, когда ты писал этот комментарий!
Приятное


1

PHP, 65 63 байта

while(count(count_chars($x=rand(1,10**$argn),1))<$argn);echo$x;

принимает данные от STDIN; бежать с-nR .

создать случайное число между 1и 10^Nвключительно;
Повторите, пока количество различных символов < N.


1
while(count(count_chars($x=rand(1,10**$argn),1))<$argn);echo$x;-2 байта
Йорг Хюльсерманн

0

Mathematica 65 60 байт

0For[a=11,Max@DigitCount@a>1,a=RandomInteger[10^{#-1,#}]]+a&

Вот более быстрая версия, но добавляет 9 байтов:

FromDigits@Join[f=(s=RandomSample)[r=Range@9,1],s[r/.f[[1]]->0,#-1]]&

0

Java 9 JShell, 86 байт

n->new Random().longs(0,10).limit(n-1).reduce(new Random().nextInt(9)+1,(a,b)->a*10+b)

Попробуйте онлайн!

Примечание: я не считаю импорт, поскольку эти пакеты импортируются по умолчанию в JShell, но для JShell я не знаю ссылки Try-it-online, поэтому я предоставил одну для Java 9 с кодом верхнего и нижнего колонтитула для заставить это работать в этом контексте. В JShell вы можете просто сделать:

jshell> Function<Integer,Long> f =
   ...> n->new Random().longs(0,10).limit(n-1).reduce(new Random().nextInt(9)+1,(a,b)->a*10+b)
f ==> $Lambda$27/633070006@5702b3b1

А потом:

jshell> f.apply(6)
$26 ==> 746202

Как это работает:

Мы определяем функцию от Integer до Long и создаем бесконечный поток случайных длин в диапазоне от 0-9, ограничиваем ее первыми n-1 элементами, затем уменьшаем ее со случайным int от 1-9 в качестве начального значения и функция, которая умножает значение на 10 и добавляет следующее значение из потока.

Я использовал longs, так что это должно работать примерно до 18 цифр (n = 18).


0

C 96 93 байта

f(n){char d[11],i=0,r;for(;i++^10;d[i-1]=d[r=rand()%i],d[r]=47+i);*d^48?d[n]=0,puts(d):f(n);}

Инициализация Фишера-Йейтса до тех пор, пока первая цифра не станет нулевой.

Равномерно, предполагая rand()%iравномерно. (Так как для большинства яRAND_MAX/i оставляю небольшой остаток, существует очень маленький уклон. Этот уклон уменьшается с ростом RAND_MAX.)

Посмотрите, как работает онлайн .

Смотрите, генерируйте правильные числа, когда n равно 2, как показано в вопросе .


0

Аксиома, 191 байт

g(a:NNI):Complex INT==(a<1 or a>9=>%i;r:List NNI:=[];b:=a;repeat(a=0=>break;d:=random()$INT rem 10;a=b and d=0=>0;~member?(d,r)=>(a:=a-1;r:=cons(d,r)));reduce(+,[r.i*10^(i-1)for i in 1..#r]))

Развернись, результат теста

-- Return one number of 'a' different random digits if 0<a<10
f(a:NNI):Complex INT==
    a<1 or a>9=>%i
    r:List NNI:=[];b:=a
    repeat
       a=0=>break
       d:=random()$INT rem 10
       a=b and d=0  =>0
       ~member?(d,r)=>(a:=a-1;r:=cons(d,r))
    reduce(+,[r.i*10^(i-1)for i in 1..#r])

(4) -> [[i,g(i)] for i in 0..10]
   (4)
   [[0,%i], [1,9], [2,76], [3,135], [4,6810], [5,48675], [6,415768],
    [7,7461539], [8,98421537], [9,825046739], [10,%i]]
                                          Type: List List Complex Integer
(5) -> [[i,g(i)] for i in [3,3,3,3,3,3,3,3,3]]
   (5)
   [[3,653],[3,128],[3,254],[3,268],[3,914],[3,594],[3,276],[3,240],[3,398]]


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.