Leí esta pregunta y pensé que sería un buen desafío.
Tarea
Dar una entrada 0<n<10
generar un número aleatorio con
- exactamente n dígitos
- el primero no es
0
- asi que
f(n)>10**(n-1)-1
- asi que
- dígitos distintos
Criterios ganadores
Este es el código de golf, 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=2
es:
[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
Roman Gräf
fuente
fuente
Respuestas:
Python 2 , 77 bytes
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
n
dígitos enumerados.fuente
9
o10
.[1::3]
funciona convertirlo de una lista a una cadena? Nunca he visto eso antes.[
.[1::3]
obtiene el personaje en el índice 1, luego cada tercio. Para[1, 2, 3]
, eso da123
, omitiendo los corchetes, comas y espacios.[1, 2, 3]
ya había sido encadenado y que las comas y los espacios necesitaban saltarse. ¡Gracias!Brachylog ,
910 bytesPrué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
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
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
≜₁
antes de darme cuenta de que se había agregado debido a este desafíoJalea , 9 bytes
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:
¿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
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).fuente
Jalea , 11 bytes
Pruébalo en línea!
Cómo funciona
fuente
JavaScript (ES6),
72717069 bytesEsta 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 quey|z
devuelve 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:
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/z
al principio para generarNaN
si ambos son 0), pero en algún momento me di cuenta de que simplemente funcionaríay|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 conx-1
yy|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.fuente
ClojureScript,
8179 bytesEsta es una función anónima, por lo que debe usarla así:
Donde reemplazas
{arguments}
con tus argumentos.Puede probar el código aquí (ClojureScript REPL).
¡Gracias
@cliffroot
por reducir 2 bytes!Código ampliado:
Explicación:
Voy a ir a través de las líneas una por una, usando una entrada de ejemplo de
8
.Bastante simple, esto define la función
random-digits
con un argumento, llamadon
. En mi respuesta, utilicé una función anónima (#(...)
) para guardar bytes.Examinemos el interior
let
, de adentro hacia afuera:En ClojureScript (y Clojure),
(range n)
es similar a Pythonrange(n)
: le da una lista con cada número desde0
hastan - 1
(9
en este caso).shuffle
toma 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:(subvec vector start end)
toma un vector (solo un vector) y devuelve un vector que tiene todos los elementos desde el índicestart
hastaend
. En este caso, estamos tomando elementos del elemento0
th al argumento dado arandom-digits
. Si aplicamos eso a nuestro ejemplo, obtenemos:Esta
if
declaración verifica si el primer elemento denum-vector
es a0
.Si es así
0
, llamamos a la función nuevamente, con el argumenton
, utilizandorecur
.Si no es así
0
:(apply function list)
toma una lista y los escupe en la función como argumentos. Por ejemplo:Se convierte en:
Que es igual
9
.(str items)
convierte cada elemento enitems
una cadena y luego los concatena.int
convierte cualquier cosa en un entero. Entonces, si aplicamos esto a nuestro ejemplo, obtenemos:Cuál es nuestra respuesta final.
fuente
(int string)
lugar de(Integer/parseInt string)
:)read-string
en Clojure, pero no es mucho mejor ...#(let[a(subvec(shuffle(range 10))0 %)](if(=(a 0)0)(recur %)(int(apply str a))))
muevenapply str
parte al final, permiten comparar en0
lugar de\0
y usan ensubvec
lugar detake
permiten usar el vector como una función y, por lo tanto, eliminarfirst
shuffle
convirtió la colección en unvec
. ¡Gracias!Python 2,
898180 bytesPruébalo en línea
fuente
99**n
, solo para asegurarme de tenerlos a todos. : Dif`set(`i`)`[5*n:]]
.R, 45 bytes
fuente
k=0
ya 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.while(!k[1])
Funcionaría para ahorrar 2 bytes?Bash + GNU utils, 46
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.
fuente
Java 7,
150147145134 bytes-2 bytes gracias a @TheLethalCoder
(antiguo) Explicación:
Código de prueba:
Pruébalo aquí
Salida de ejemplo:
fuente
n->...
o es Java 8+?for(int l,x;(l=r.length())<n;)
y debe guardar un byte.n->...
es Java 8. Personalmente, prefiero codegolf en Java 7, aunque 8 siempre es más corto.Perl 6 , 44 bytes
Intentalo
Expandido:
fuente
PHP, 67 bytes
Versión en línea
Todas las versiones basadas en barajar los dígitos del 0-9
71 bytes
73 bytes
fuente
MATL , 15 bytes
¡Pruébalo en MATL Online!
Explicación
fuente
Jalea , 12 bytes
Actualmente, un byte detrás de mi otra respuesta de Jelly, pero realmente me gusta esta.
Pruébalo en línea!
Cómo funciona
fuente
APL (Dyalog) ,
271917 bytesRequiere
⎕IO←0
cuál es el predeterminado en muchos sistemas.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 positivoshasta que ...
⊃⍺
el primer dígito del último intento×
sea positivofuente
Python 2 ,
100939290 bytesGracias a @ mbomb007 por eliminar 2 bytes
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.
fuente
return(n==len(set(`k`)))*k or f(n)
. Pruébelo en líneaPyth , 11 bytes
Utiliza el mismo algoritmo que la respuesta de Dennis .
Pruébalo en línea!
fuente
Perl, 48 bytes
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.
fuente
Lote, 156 bytes
x
mantiene una máscara de bits de dígitos usados.f
indica 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=10
podría ser compatible con 165 bytes:(
r
contiene 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!):El enfoque original para 170 bytes también funcionó para
n=10
:Utiliza la manipulación de cadenas para detectar dígitos duplicados.
fuente
Bash , 66 bytes
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!
fuente
Pyth,
1528 bytesPruébalo aquí
fuente
0
, así que creo que querrás cambiar^TttQ
a^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.C #,
127132128126125 bytes¡Pruébelo en línea!
Tomó prestada la idea de la respuesta de @ KevinCruijssen para inicializar el azar
r
, en laif
declaració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
while
bucle:fuente
0
, sería el primer intentoif(s.Length<1&r>0)
que sea falso, pero luego se va a hacerif(!s.Contains(r+""))
lo que es cierto y todavía anexados"0"
as
como primer dígito..Next(10)
... con un;
. Así que no hay más mejoras allí, pero es una buena idea.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 bytesEste genera un número aleatorio real
Pruébalo en línea!
C (gcc) ,
8785 bytesAquí está imprimiendo una cadena de dígitos.
Pruébalo en línea!
fuente
PHP,
6563 bytestoma entrada de STDIN; correr con
-nR
.crear un número aleatorio entre
1
e10^N
inclusive;repita mientras el recuento de caracteres distintos es <
N
.fuente
while(count(count_chars($x=rand(1,10**$argn),1))<$argn);echo$x;
-2 BytesMathematica
6560 BytesAquí hay una versión más rápida pero agrega 9 bytes:
fuente
Java 9 JShell, 86 bytes
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:
Y entonces:
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).
fuente
C,
9693 bytesFisher-Yates baraja la inicialización hasta que el primer dígito no sea cero.
Es uniforme, suponiendo que
rand()%i
sea uniforme. (Como para la mayoría de lasRAND_MAX/i
hojas 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 .
fuente
Axioma, 191 bytes
deshacerse de él, resultado de la prueba
fuente
Medusa , 17 bytes
Pruébalo en línea!
Tenedor de Dennis 'Jelly respuesta .
fuente
Rubí,
5352 bytesMezcle hasta que el primer dígito no sea 0, luego combine los dígitos y conviértalos en un entero.
Pruébalo en línea!
fuente