Obtenga un número aleatorio de n dígitos con dígitos distintos y primero no un 0

22

Leí esta pregunta y pensé que sería un buen desafío.

Tarea

Dar una entrada 0<n<10generar un número aleatorio con

  • exactamente n dígitos
  • el primero no es 0
    • asi que f(n)>10**(n-1)-1
  • dígitos distintos

Criterios ganadores

Este es el por lo que gana el código más corto.

Aleatorio

Me refiero a distribuir uniformemente al azar. Desde el punto de vista del programa, cada número posible tiene la misma posibilidad. Si el idioma en el que está escribiendo tiene un generador de números aleatorios extraño, está bien usarlo.

Ejemplo

La lista de valores para seleccionar aleatoriamente para n=2es:

[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]
Roman Gräf
fuente
44
Debe evitarse la
flawr
volver como un entero, no una cadena, ¿sí?
Giuseppe
@Giuseppe genera un número aleatorio
mbomb007
44
Pienso en esto cada vez que alguien hace una pregunta de número aleatorio xkcd.com/221
Thunda
1
@ ais523 "Dar una entrada 0 <n <10 generar un número aleatorio con"
cleblanc

Respuestas:

17

Python 2 , 77 bytes

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

Pruébalo en línea!

Baraja la lista de 10 dígitos hasta que no comience con 0, luego crea un número con los primeros ndígitos enumerados.

xnor
fuente
Definitivamente corre más rápido y con menos memoria para la entrada de 9o 10.
mbomb007
Solución ordenada! ¿Podría explicar cómo [1::3]funciona convertirlo de una lista a una cadena? Nunca he visto eso antes.
Julian Wolf
@JulianWolf Solo funciona si cada elemento de la lista tiene la misma longitud. Realmente toma la representación de cadena de la lista, luego la corta tomando cada 3er carácter después de omitir el primero [.
mbomb007
@JulianWolf [1::3]obtiene el personaje en el índice 1, luego cada tercio. Para [1, 2, 3], eso da 123, omitiendo los corchetes, comas y espacios.
Dennis
Dispara, está bien, eso tiene sentido. Estaba olvidando que [1, 2, 3]ya había sido encadenado y que las comas y los espacios necesitaban saltarse. ¡Gracias!
Julian Wolf
10

Brachylog , 9 10 bytes

{~lℕ₁≜≠}ᶠṛ

Pruébalo en línea!

Como es habitual en Brachylog, esta es una presentación de función. El enlace TIO anterior recibió un argumento de línea de comandos para convertir la función en un programa completo.

Tuve que agregar un byte adicional desde la primera versión de esto, cambiando a ℕ₁, para no permitir la salida 0 (algo que ahora se ha aclarado).

Explicación

{~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.

Bastante ineficiente, porque el intérprete genera una lista de todos los valores posibles y luego elige uno al azar (eso es lo que ᶠṛsignifica; Brachylog no tenía una opción de "elegir una solución aleatoria" en el momento en que se hizo esta pregunta).

Algunos comentarios sobre la etiqueta aquí: si se omite, la sección dentro de las llaves solo produce un valor, una restricción que representa números con la propiedad que queremos; Por lo tanto, elegir un resultado aleatorio nos da la restricción, y el intérprete genera el valor absoluto mínimo que cumple con la restricción (1, 10, 102, 1023, 10234, etc.), que no es lo que queremos. Por lo tanto, tenemos que obligarlo a construir la lista a través de una etiqueta explícita.

La mayoría de las implementaciones de Prolog que he visto tienen una función integrada para encontrar un resultado aleatorio que coincida con una restricción, pero generalmente no con una probabilidad uniforme; Sin embargo, Brachylog no tenía uno (se agregó uno en respuesta a este desafío, pero obviamente no puedo usarlo debido a las reglas de laguna). Si lo hiciera, y si sucediera para dar una probabilidad uniforme sobre este problema, este programa solo sería ~lℕ₁≠seguido por ese incorporado, para una longitud probable de 6 bytes.

Brachylog , 8 bytes, en colaboración con @Fatalize

~lℕ₁≠≜ᶠṛ

Pruébalo en línea!

Este es el tipo de truco genial de bajo nivel que solo tiene sentido con la forma en que Prolog hace las cosas, y no tiene mucho sentido cuando se describe matemáticamente.

Como antes, ~lℕ₁≠crea un valor que describe una restricción ("longitud igual a la entrada, número natural, todos los elementos diferentes"). Luego ≜ᶠgenera todos los valores posibles que cumplen con la restricción. El punto aquí es que con la secuencia de evaluación de Brachylog, no se toman decisiones reales hasta que aparece, por lo que la operación "encontrar todas las soluciones" no debe aplicarse sino al "valor específico que cumple una restricción" . Eso significa que no es necesario que {…}a seleccione su alcance, ahorrando 2 bytes.


fuente
Iba a publicar una solución ≜₁antes de darme cuenta de que se había agregado debido a este desafío
Cadena no relacionada
8

Jalea , 9 bytes

⁵*ṖQL$€MX

Pruébalo en línea! (no funcionará en TIO para n> 6 debido a la ineficiencia de la implementación)

o una implementación alternativa de lo mismo:

⁵*ṖQL$ÐṀX

¿Cómo?

¡Esto es muy astuto y muy ineficiente! Jelly hace algunas cosas útiles implícitamente cuando un átomo espera una lista pero recibe un número entero (esto es por diseño).
Este código utiliza un par de estas acciones implícitas útiles:

  • El átomo monádico , "pop", cuando se llama con una entrada entera, implícitamente hace un rango desde el cual estallar, por lo que una entrada de n primero hace [1, 2, ..., n] , luego aparece, produciendo [1, 2 , ..., n-1] .

  • El átomo monádico Q, "desduplicado" o "único", cuando se llama con una entrada entera, implícitamente hace una lista decimal para desduplicar, por lo que una entrada de n donde:
    n = d k-1 × 10 k-1 + d k-2 × 10 k-2 + ... + d 1 × 10 + d 0
    primero hace
    [d k-1 , d k-2 , ..., d 1 , d 0 ]
    y luego produce los valores únicos por primera impresión.
    Entonces, por ejemplo, n = 5835518 produciría [5, 8, 3, 1] .

Además, el átomo monádico M, "índices de elementos máximos", devuelve los índices de los elementos máximos de una lista, esto ahorra dos bytes sobre la alternativa mucho más obvia de probar la igualdad con la entrada y encontrar índices de verdad ⁵*ṖQL$€=⁸TX, o⁵*Ṗð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

Todo esto es bastante ineficiente, tanto en tiempo como en memoria: primero se hace una lista de 10 n enteros y se descarta uno, luego para cada uno de ellos se hace una lista de n enteros (no un objeto de 4 bits o enumeración elegante) y luego deduplicado. Esta desduplicación tiene una implementación completamente basada en listas (no hay conjuntos, conjuntos ordenados o diccionarios involucrados bajo el capó, se verifica la existencia de cada dígito en la lista que finalmente se genera).
Sin conexión n = 7 usa ~ 0.5GB y toma ~ 25 segundos, mientras que n = 8 usa ~ 4GB y toma ~ 5 minutos - No me he molestado en ejecutar n = 9 ya que solo tengo 16GB de RAM (supongo que tomaría ~ 45 minutos )

La implementación alternativa solo usa el ÐṀrápido incorporado para mantener el filtro mínimo (que aquí solo agrega un poco de sobrecarga en la administración para el mismo conteo de bytes).

Jonathan Allan
fuente
Oh wow. Estaba intentando algo muy parecido a esto, pero me perdí el truco de almacenar los valores para devolverlos en los índices de la lista (a través de rellenar adecuadamente la lista), en lugar de tratar de almacenarlos por separado. Este es un truco que es útil en Jelly con bastante frecuencia y siempre parece que lo echo de menos.
7

Jalea , 11 bytes

9Xœ|⁵ḶẊ¤ḣ¹Ḍ

Pruébalo en línea!

Cómo funciona

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.
Dennis
fuente
Esa es una forma muy inteligente de eliminar el duplicado ...
Leaky Nun
7

JavaScript (ES6), 72 71 70 69 bytes

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

Esta es una función recursiva que toma el número de dígitos x . El segundo parámetro y , inicialmente establecido en la cadena vacía, realiza un seguimiento del número a medida que lo generamos dígito a dígito.

Primero generamos un dígito aleatorio z con Math.random()*10|0. Ahora, queremos verificar que y no contenga z , y que y y z no sean ambos 0 .

Podemos calcular la primera condición con !y.match(z). y.match(z)devuelve una matriz (siempre verdadera) si y contiene z , nulo (falso) de lo contrario; el !convierte esto a un booleano y lo invierte.

La segunda condición se verifica con y|z. Aunque y es una cadena, JS lo convierte implícitamente en un entero cuando se usa |. Este es un entero positivo si y ya contiene dígitos, 0 de lo contrario. El resultado neto es que y|zdevuelve 0 si f y está vacío y z es 0 , o un entero positivo de lo contrario.

Si ambas condiciones son verdaderas, entonces agregamos el dígito a y , decrementamos x , y comenzamos el proceso nuevamente. De lo contrario, simplemente volvemos al principio y esperamos que el siguiente dígito aleatorio funcione. Cuando x alcanza 0 , simplemente devolvemos la cadena vacía para finalizar la recursión.


Versión previa:

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

Esta es una función recursiva que toma el número de dígitos. El segundo parámetro inicialmente indefinido, y , es una tabla de búsqueda de 10 bits que nos dice qué dígitos ya tenemos, convenientemente almacenados como un entero.

Primero generamos un dígito aleatorio z con Math.random()*10|0. Ahora, queremos comprobar que el z 'th bit menos significativo de y no está establecido, y que y y z no son ambos 0 .

Podemos calcular la primera condición con ~y>>z&1; invierta y , desplace los bits z hacia la derecha y tome solo el bit menos significativo. Esto da 1 si aún no hemos generado el dígito en cuestión, o 0 en caso contrario.

La segunda condición fue inicialmente bastante difícil de resolver (intenté usarla y/zal principio para generar NaNsi ambos son 0), pero en algún momento me di cuenta de que simplemente funcionaría y|z. El resultado es 0 si f y y z son 0 ; un entero positivo de lo contrario.

Si ambas condiciones son verdaderas ( ~y>>z&1&&y|z), generamos el resto del número y anteponemos z . El resto del número se genera llamando nuevamente a la función con x-1y y|1<<z( y , pero con el bit en el índice z establecido en 1 ). Cuando x alcanza 0 , simplemente devolvemos la cadena vacía para finalizar la recursión.

ETHproducciones
fuente
5

ClojureScript, 81 79 bytes

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

Esta es una función anónima, por lo que debe usarla así:

(#(...) {arguments})

Donde reemplazas {arguments}con tus argumentos.

Puede probar el código aquí (ClojureScript REPL).

¡Gracias @cliffrootpor reducir 2 bytes!


Código ampliado:

(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)))))

Explicación:

Voy a ir a través de las líneas una por una, usando una entrada de ejemplo de 8.


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

Bastante simple, esto define la función random-digitscon un argumento, llamado n. En mi respuesta, utilicé una función anónima ( #(...)) para guardar bytes.


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

Examinemos el interior let, de adentro hacia afuera:

(shuffle (range 10))

En ClojureScript (y Clojure), (range n)es similar a Python range(n): le da una lista con cada número desde 0hasta n - 1( 9en este caso).

shuffletoma una lista y devuelve un vector (que es ligeramente diferente de una lista) con todos sus elementos barajados. Entonces, usando nuestro ejemplo, obtenemos algo como esto:

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

(subvec {see above} 0 n)

(subvec vector start end)toma un vector (solo un vector) y devuelve un vector que tiene todos los elementos desde el índice starthasta end. En este caso, estamos tomando elementos del elemento 0th al argumento dado a random-digits. Si aplicamos eso a nuestro ejemplo, obtenemos:

[1 0 8 3 6 7 9 2]

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

Esta ifdeclaración verifica si el primer elemento de num-vectores a 0.

Si es así 0, llamamos a la función nuevamente, con el argumento n, utilizando recur.

Si no es así 0:


(int (apply str num-vector))

(apply function list)toma una lista y los escupe en la función como argumentos. Por ejemplo:

(apply + [2 3 4])

Se convierte en:

(+ 2 3 4)

Que es igual 9.

(str items)convierte cada elemento en itemsuna cadena y luego los concatena. intconvierte cualquier cosa en un entero. Entonces, si aplicamos esto a nuestro ejemplo, obtenemos:

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

Cuál es nuestra respuesta final.

clismique
fuente
2
Tengo que amar ClojureScript por permitir en (int string)lugar de (Integer/parseInt string):)
cliffroot
1
@cliffroot Quiero decir, puedes hacerlo read-stringen Clojure, pero no es mucho mejor ...
clismique
2 bytes guardados #(let[a(subvec(shuffle(range 10))0 %)](if(=(a 0)0)(recur %)(int(apply str a))))mueven apply strparte al final, permiten comparar en 0lugar de \0y usan en subveclugar de takepermiten usar el vector como una función y, por lo tanto, eliminarfirst
cliffroot
@cliffroot Huh, no sabía que shuffleconvirtió la colección en un vec. ¡Gracias!
Tendré
5

Python 2, 89 81 80 bytes

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

Pruébalo en línea

mbomb007
fuente
No creo que necesite un valor inicial para el rango.
Dennis
¡Agradable! Eso lo ralentizará. : D Lástima que no pueda usar un generador en lugar de una lista.
mbomb007
Solo en un 11%. Caída en un balde para el código de golf.
Dennis
Sí, debería usar 99**n, solo para asegurarme de tenerlos a todos. : D
mbomb007
Miré hacerlo de esta manera también, pero obtuve 80, usando if`set(`i`)`[5*n:]].
Jonathan Allan
5

R, 45 bytes

k=0
i=scan()
while(!k[1])k=sample(0:9)[1:i]
k
Neil
fuente
Creo que puede establecerlo k=0ya que es un vector implícito de longitud uno, y puede usar i = scan () para tomar la entrada de stdin como un número. Tampoco estoy seguro de que una lista de dígitos sea una presentación "correcta", pero no soy el juez.
Giuseppe
@Giuseppe Gracias por el aporte, actualicé tanto tu sugerencia (en ambas publicaciones), gracias.
Neil
¿ while(!k[1])Funcionaría para ahorrar 2 bytes?
BLT
@BLT Actualizado, gracias.
Neil
3

Bash + GNU utils, 46

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

Pruébalo en línea .

Esto lleva mucho tiempo para n más grande , alrededor de 30 s para n = 7, y aumenta 10 veces para cada incremento, por lo que probablemente sea de 8 a 9 horas para n = 10.

Trauma digital
fuente
por la cuestión, n = 10 no tiene necesidad de trabajo, incluso, mucho menos ser rápido
ysth
3

Java 7, 150 147 145 134 bytes

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 bytes gracias a @TheLethalCoder

(antiguo) Explicación:

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

Código de prueba:

Pruébalo aquí

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));
  }
}

Salida de ejemplo:

7194
8672953041
Kevin Cruijssen
fuente
¿No puedes usar una expresión lambda aquí? es decir, ¿ n->...o es Java 8+?
TheLethalCoder
1
También puede pedir prestado el truco que acabo de usar en mi respuesta, establecer la longitud en la verificación de comparación, es decir, for(int l,x;(l=r.length())<n;)y debe guardar un byte.
TheLethalCoder
1
@TheLethalCoder Ah, por supuesto, gracias. ¡Gran trabajo de equipo! ;) Y sí, n->...es Java 8. Personalmente, prefiero codegolf en Java 7, aunque 8 siempre es más corto.
Kevin Cruijssen
2

Perl 6 , 44 bytes

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

Intentalo

Expandido:

{  # 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)
}
Brad Gilbert b2gills
fuente
2

PHP, 67 bytes

Versión en línea

Todas las versiones basadas en barajar los dígitos del 0-9

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

71 bytes

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

73 bytes

for($a=range(0,9);!$a[0];)shuffle($a);echo join(array_slice($a,0,$argn));
Jörg Hülsermann
fuente
2

MATL , 15 bytes

`4Y2GZr1)48=]8M

¡Pruébalo en MATL Online!

Explicación

`        % 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
Luis Mendo
fuente
2

Jalea , 12 bytes

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

Actualmente, un byte detrás de mi otra respuesta de Jelly, pero realmente me gusta esta.

Pruébalo en línea!

Cómo funciona

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.
Dennis
fuente
2

APL (Dyalog) , 27 19 17 bytes

Requiere ⎕IO←0cuál es el predeterminado en muchos sistemas.

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

Pruébalo en línea!

Mezcla los dígitos hasta que sea válido:

10⊥ decodificar desde dígitos de base 10 a número regular,

 luego

 primeros elementos de

{... }⍣{... } repitiendo la función ...
?⍨10 baraja los primeros diez enteros positivos
hasta que ...
⊃⍺ el primer dígito del último intento
× sea ​​positivo

Adán
fuente
1

Python 2 , 100 93 92 90 bytes

Gracias a @ mbomb007 por eliminar 2 bytes

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

Intenta números en el requerido hasta que se encuentre uno con dígitos únicos. Apuesto a que hay una manera mucho más limpia de hacer esto, pero no se me ocurre ninguna.

Julian Wolf
fuente
return(n==len(set(`k`)))*k or f(n). Pruébelo en línea
mbomb007
1

Pyth , 11 bytes

jk<{+OS9.ST
jk<{+OS9.STQ implicit Q

       9     9
      S      [1,2,3,4,5,6,7,8,9]
     O       random element

          T  10
        .S   random permutation of [0,1,2,3,4,5,6,7,8,9]

    +        add the results from the previous two paragraphs together
   {         deduplicate
  <        Q first (input) elements
jk           join by empty string

Utiliza el mismo algoritmo que la respuesta de Dennis .

Pruébalo en línea!

Monja permeable
fuente
1

Perl, 48 bytes

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

Explicación:

Genere repetidamente enteros aleatorios de 1 a 10 ** $ n-1, rechazándolos hasta que haya uno de la longitud correcta (por lo menos 10 ** ($ n-1)) sin dígitos repetidos.

ysth
fuente
1

Lote, 156 bytes

@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

xmantiene una máscara de bits de dígitos usados. findica el número de dígitos disponibles (contando desde 9). Los dígitos aleatorios se generan hasta que se encuentra un dígito no utilizado. n=10podría ser compatible con 165 bytes:

@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

( rcontiene un cero inicial adicional porque es más golfista de esa manera). Enfoque anterior para 165 bytes con mayúscula especial el primer dígito, y también funcionó n=10(¡la versión numérica en realidad tomó 166 bytes!):

@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%

El enfoque original para 170 bytes también funcionó para 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%

Utiliza la manipulación de cadenas para detectar dígitos duplicados.

Neil
fuente
1

Bash , 66 bytes

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

Pruébalo en línea!

Directamente, usa shuf, xargs se usa para unir líneas y continúa intentando mientras la combinación comienza con 0.

No se puede vencer a 46 char de otra respuesta, ¡pero es rápido!

marcom
fuente
1

Pyth, 15 28 bytes

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

Pruébalo aquí

Maria
fuente
1
Bienvenido a PPCG, y excelente trabajo usando un lenguaje de golf desde el principio :-) Veo 2 pequeños problemas: 1) parece que el segundo dígito siempre es 0, así que creo que querrás cambiar ^TttQa ^TtQ(-1 byte, ¡prima!). 2) todos los dígitos en la salida deben ser únicos, por lo que tendrá que forzar que eso suceda de alguna manera.
ETHproductions
@ETHproductions Arg !! Gracias por señalar eso. Lo he arreglado
Maria
1

C #, 127 132 128 126 125 bytes

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;};

¡Pruébelo en línea!

Tomó prestada la idea de la respuesta de @ KevinCruijssen para inicializar el azar r, en la ifdeclaración para guardar 2 bytes.

Estoy bastante seguro de que esto se puede jugar más, pero no tengo tiempo en este momento.


Versión anterior que usa un whilebucle:

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;};
TheLethalCoder
fuente
No creo que esto sea correcto. Digamos que el primer número entero aleatorio es 0, sería el primer intento if(s.Length<1&r>0)que sea falso, pero luego se va a hacer if(!s.Contains(r+""))lo que es cierto y todavía anexados "0"a scomo primer dígito.
Kevin Cruijssen
@KevinCruijssen Arreglado y jugando al golf aún más
TheLethalCoder
1
@KevinCruijssen Ah, lo resolví, en tu ejemplo no terminas el .Next(10)... con un ;. Así que no hay más mejoras allí, pero es una buena idea.
TheLethalCoder
1
Acabo de publicarlo. Y vaya, tienes razón, me perdí ese punto y coma. Sin embargo, todavía puedes 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;};
jugarlo así
1
@KevinCruijssen ¡Acabo de tomar prestada la idea de tu respuesta mientras escribías ese comentario! Buena mejora gracias
TheLethalCoder
1

C (gcc) , 123 122 100 95 104 103 99 97 bytes

Este genera un número aleatorio real

j;f(n){for(int i,k=n,s[10]={j=0};n;s[i+=i?0:k==n]=!s[i]?j+=i*pow(10,--n):1)i=rand()%10;return j;}

Pruébalo en línea!

C (gcc) , 87 85 bytes

Aquí está imprimiendo una cadena de dígitos.

f(n){for(int i,k=n,s[10]={0};n;s[i+=i?0:k==n]=!s[i]?--n,putchar(48+i):1)i=rand()%10;}

Pruébalo en línea!

cleblanc
fuente
1

PHP, 65 63 bytes

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

toma entrada de STDIN; correr con -nR.

crear un número aleatorio entre 1e 10^Ninclusive;
repita mientras el recuento de caracteres distintos es < N.

Tito
fuente
1
while(count(count_chars($x=rand(1,10**$argn),1))<$argn);echo$x;-2 Bytes
Jörg Hülsermann
0

Mathematica 65 60 Bytes

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

Aquí hay una versión más rápida pero agrega 9 bytes:

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

Java 9 JShell, 86 bytes

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

Pruébalo en línea!

Nota: No estoy contando las importaciones ya que esos paquetes se importan de manera predeterminada en JShell, pero no conozco ningún enlace de Try-it-online para JShell, por lo que proporcioné uno para Java 9 con código de encabezado y pie de página para haz que funcione en ese contexto. En JShell solo puedes hacer:

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

Y entonces:

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

Cómo funciona:

Definimos una función de Entero a Largo y creamos un flujo infinito de largos aleatorios en el rango de 0-9, lo limitamos a los primeros elementos n-1, luego lo reducimos con un int aleatorio de 1-9 como valor inicial y una función que multiplica el valor por 10 y agrega el siguiente valor de la secuencia.

Utilicé longs, por lo que esto debería funcionar para hasta aproximadamente 18 dígitos (n = 18).

David Conrad
fuente
0

C, 96 93 bytes

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);}

Fisher-Yates baraja la inicialización hasta que el primer dígito no sea cero.

Es uniforme, suponiendo que rand()%isea ​​uniforme. (Como para la mayoría de las RAND_MAX/ihojas deja un pequeño resto, hay un sesgo muy pequeño. Este sesgo se hace más pequeño a medida que RAND_MAX se hace más grande).

Véalo trabajar en línea .

Vea que genera números correctos para cuando n es igual a 2, como se muestra en la pregunta .

2501
fuente
0

Axioma, 191 bytes

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]))

deshacerse de él, resultado de la prueba

-- 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]]
RosLuP
fuente
0

Rubí, 53 52 bytes

Mezcle hasta que el primer dígito no sea 0, luego combine los dígitos y conviértalos en un entero.

->n{a=*0..9;a.shuffle!while a[0]==0;eval a[0,n]*''}

Pruébalo en línea!

Tinta de valor
fuente