La aleatoriedad es divertida. Los desafíos sin sentido son divertidos.
Escriba una función que, dada la entrada de enteros n
, generará un conjunto (desordenado, único) de n
enteros exactamente aleatorios entre 1
e n^2
(inclusive) de modo que la suma de todos los enteros sea igual a n^2
.
La aleatoriedad no tiene que ser uniforme, siempre que cada conjunto válido tenga una probabilidad distinta de cero.
La respuesta más corta en bytes (por cada idioma) gana.
Ejemplos
Input (n) = 1, Target (n^2) = 1
Sample of possible outputs:
1
Input = 2, Target = 4
Sample of possible outputs:
3, 1
1, 3
Input = 3, Target = 9
Sample of possible outputs:
6, 1, 2
3, 5, 1
4, 3, 2
Input = 4, Target = 16
Sample of possible outputs:
1, 3, 5, 7
2, 4, 1, 9
8, 3, 1, 4
Input = 5, Target = 25
Sample of possible outputs:
11, 4, 7, 1, 2
2, 3, 1, 11, 8
6, 1, 3, 7, 8
Input = 8, Target = 64
Sample of possible outputs:
10, 3, 9, 7, 6, 19, 8, 2
7, 16, 2, 3, 9, 4, 13, 10
7, 9, 21, 2, 5, 13, 6, 1
Tarea adicional: ¿hay una fórmula para calcular el número de permutaciones válidas para un determinado n
?
code-golf
random
combinatorics
Skidsdev
fuente
fuente
Respuestas:
Brachylog (v2), 15 bytes (aleatorio) o 13 bytes (todas las posibilidades)
Aleatorio
Pruébalo en línea!
Envío de funciones (visto en TIO con un contenedor que lo convierte en un programa completo).
Explicación
Todas las posibilidades
Pruébalo en línea!
Envío de funciones, que genera todas las salidas posibles.
Explicación
Estoy bastante sorprendido de que
∧≜
funcione (normalmente tendrías que escribir∧~≜
para forzar la salida en lugar de la entrada), pero resulta que≜
tiene un supuesto de entrada = salida, por lo que no importa en qué dirección ejecutarlo.Tarea de bonificación
Para obtener una idea de la secuencia del número de posibilidades, creé un contenedor TIO diferente que ejecuta el programa en enteros sucesivos para dar la secuencia de conteos de salida:
Un viaje a OEIS descubre que esta es una secuencia conocida, A107379 , descrita más o menos como en la pregunta (al parecer, obtiene la misma secuencia si la restringe a números impares). La página enumera varias fórmulas para la secuencia (aunque ninguna es particularmente simple; la segunda parece una fórmula directa para el valor pero no entiendo la notación).
fuente
x^(n*(n-1)/2)
expansión en serie deProduct_{k=1..n} 1/(1 - x^k)
" (desafortunadamente no es directo en absoluto)A≠≜₁ᵐ
) hace que el tiempo de ejecución sea mucho más rápido en promedio.05AB1E , 11 bytes
Pruébelo en línea o verifique todos los casos de prueba .
Explicación:
fuente
Python (2 o 3), 85 bytes
Pruébalo en línea!
fuente
R ,
68, 7548 bytes (aleatorio) y 70 bytes (determinista)Método de muestreo de rechazo de @ Giuseppe:
Pruébalo en línea!
Golfed original:
Pruébalo en línea!
El
*!!1:2
negocio es evitar la forma extraña desample
actuar cuando el primer argumento tiene longitud 1.fuente
p
directamente como índice en lugar de calcularlo y volver a usarlo debería ahorrar algunos bytes.function(n){while(sum(F)!=n^2)F=sample(n^2,n);F}
48 también ...sample(2,1)
que suceden=2
. Así querep
solo garantiza que esto nunca sucederá. Puede haber una mejor manera, pero esto fue rápido y estaba enojadosample
.x*!!1:2
overrep(x,2)
si su meta pregunta obtiene un no.Jalea , 9 bytes
Pruébalo en línea!
Genere todas las combinaciones n de la lista [1..n²], filtre para mantener aquellas con suma n², luego elija una aleatoria.
fuente
Java 10,
250242222 bytes-20 bytes gracias a @nwellnhof .
Cuidado, Java viene ... Es 'solo' cinco veces más que las otras cuatro respuestas combinadas, así que no está mal, supongo ... rofl.
Que se ejecuta
n=1
a través den=25
(combinado) en menos de 2 segundos sin embargo, así que probablemente publicar una versión modificada de la versión de la velocidad de este desafío (que es actualmente todavía en la zona de pruebas) también.Pruébalo en línea.
Explicación:
En pseudocódigo hacemos lo siguiente:
1) Generar una matriz de tamaño
n+1
que contiene:0
,n
cuadrado, yn-1
cantidad de números enteros aleatorios en el rango de[0, n squared)
2) Ordenar esta matriz
3) Crear una segunda matriz de tamaño
n
que contiene las diferencias hacia adelante de paresEstos tres primeros pasos nos darán una matriz que contiene
n
al azar enteros (en el rango[0, n squared)
que suma aln
cuadrado.4a) Si no todos los valores aleatorios son únicos, o alguno de ellos es 0: intente nuevamente desde el paso 1
4b) De lo contrario: devuelva esta matriz de diferencias como resultado
En cuanto al código real:
fuente
n=25
¡En menos de 2 segundos es impresionante! Tendré que leer la explicación y ver cómo lo hace. ¿Sigue siendo un método de fuerza bruta?[0, n squared)
primero, y luego calcula las diferencias entre esos valores aleatorios ordenados (incluidos el inicio0
y el finaln squared
. Así que estoy bastante seguro de que esas diferencias también son uniformes. Pero de nuevo , No estoy seguro de cómo demostrarlo. La uniformidad en la aleatoriedad no es realmente mi experiencia tbh.d
o me falta algo?Perl 6 , 41 bytes
Pruébalo en línea!
(1 .. $_²)
es el rango de números del 1 al cuadrado del número de entrada.pick($_)
elige aleatoriamente un subconjunto distinto de ese rangoxx *
replica la expresión anterior infinitamentefirst *.sum == $_²
selecciona el primero de esos conjuntos de números que suman al cuadrado del número de entradafuente
Pyth,
1312 bytesPruébelo en línea aquí . Tenga en cuenta que el intérprete en línea se encuentra con un MemoryError para entradas mayores de 5.
Editar: guardado un byte adoptando un enfoque alternativo. Versión previa:
Of&qQlT{IT./*
fuente
Python 3 ,
136134127121114bytesPruébalo en línea!
Un comentarista me corrigió, y esto ahora alcanza la profundidad máxima de recursión en f (5) en lugar de f (1). Mucho más cerca de ser una respuesta competitiva real.
Lo he visto hacer f (5) una vez , y estoy trabajando en tratar de implementar esto con shuffle.
Intenté hacer algunas expresiones lambda para
s=...
, pero eso no ayudó en bytes. Quizás alguien más pueda hacer algo con esto:s=(lambda n:{randint(1,n*n)for _ in range(n)})(n)
Gracias a Kevin por eliminar otros 7 bytes.
fuente
f(1)
, la única matriz posible que debería ser generablen=1
es que[1]
también hay una gran cantidad de espacios en blanco extraños para eliminar aquí. Recuerde que este es un desafío de código de golf, por lo que el objetivo es lograr el bytecount más bajorange(1,n)
->range(n)
Creo que debería resolver el error.return len(s)==n and sum(s)==n*n and s or f(n)
( Pruébelo en línea 114 bytes ).APL (Dyalog Unicode) , SBCS de 20 bytes
Prefijo anónimo lambda.
Pruébalo en línea!
{
...}
"dfn";⍵
es argumento⍵*2
cuadrar el argumentos←
asignar as
(para s quare)⍵?
encuentren
índices aleatorios de 1 ...s
sin reemplazoc←
asignar ac
(para c andidate)+/
sumaloss=
comparar cons
:
si es igualc
devolver al candidato⋄
más∇⍵
recurse en el argumentofuente
APL (Dyalog Classic) , 18 bytes
Pruébalo en línea!
usos
⎕io←1
⍳
genera los números1 2 ... n
(
...)⍣(
...)
siga aplicando la función de la izquierda hasta que la función de la derecha devuelva verdadero≢
longitud, es decirn
≢?≢×≢
elijan
enteros al azar distintos entre 1 yn
2+.-∘≢
reste la longitud de cada número y suma0=
si la suma es 0, deje de repetir, de lo contrario intente nuevamentefuente
MATL ,
1813 bytesPruébalo en línea!
fuente
Japt, 12 bytes
Intentalo
fuente
à
debería estar bien.Java (JDK) , 127 bytes
Pruébalo en línea!
Bucle infinito hasta que coincida un conjunto con los criterios.
Espero que tengas tiempo, ¡porque es muy lento! Ni siquiera puede llegar a 10 sin tiempo de espera.
fuente
if(r.size()==n&s==0)
aif(r.size()+s==n)
.s>0
, por lo que el tamaño puede ser mayor quen
. Ok, en ese caso no funciona.n
es una constante, pero desafortunadamente ambass
yr.size()
son variables que pueden ser tanto inferiores como superiores0
yn
respectivamente.Lote,
182145 bytesExplicación: Calcula la selección mínima y máxima permitida, dado que los números deben seleccionarse en orden descendente, y elige un valor aleatorio dentro del rango. Ejemplo para una entrada de
4
:fuente
JavaScript,
647291261260259251239 bytesGracias a @Veskah por -10 bytes en la versión original y "Oh sí, estás enviando todos los conjuntos mientras que el desafío pide que se devuelva uno aleatorio"
Pruébalo en línea!
Cree una matriz de
n^2
índices basados en 1, ordene la matriz al azar, corten
elementos de la matriz. Mientras que la suma de los elementos aleatorios no es igual a lan^2
matriz de bucle de elementos aleatorios; si la suma de los elementos de la matriz es mayor que eln^2
elemento actual-1
no es igual a cero o el elemento actual-1
no está en la matriz actual, reste1
; si la suma de la matriz es menor quen^2
y el elemento actual+1
no está en la matriz, agregue1
al elemento. Si la suma de la matriz es igual an^2
romper el bucle, la matriz de salida.fuente
k++
while
bucles probablemente también podrían reducirse al cuerpo de una sola función que acepta parámetros; y podría sustituir operadores condicionales (ternarios) por lasif..else
declaraciones; entre otras partes del código que probablemente podrían ajustarse para el golf; ieg, eliminandolet
declaraciones.if..else
n
?" . probando resultado esperado si el algoritmo devuelve constantemente paran^2
arrays de salida generadas en una sola llamada a la función, y considerando simultáneamente las similitudes a esta pregunta N N-dimensional ^ array N lleno de N .Japt , 20 bytes
Pruébalo en línea!
Aprovecha en gran medida la aleatoriedad "no uniforme", casi siempre genera los primeros
n
números impares, que sumann^2
. En teoría, puede generar cualquier otro conjunto válido, aunque solo he podido confirmarlo por pequeñon
.Explicación:
fuente
Ruby , 46 bytes
Pruébalo en línea!
fuente
C (gcc) ,
128125 bytesPruébalo en línea!
-3 bytes gracias a ceilingcat
NOTA: La probabilidad está muy muy lejos de ser uniforme. Vea la explicación de lo que quiero decir y un mejor medio para probar que funciona (haciendo que la distribución sea más cercana al uniforme [pero aún muy lejos de eso]).
¿Cómo?
La idea básica es elegir solo números crecientes para no preocuparse por los duplicados. Cada vez que elegimos un número, tenemos una probabilidad distinta de cero de 'omitirlo' si es posible.
x
k
y
x
No obstante, la lógica es tener la oportunidad de descartar cualquiera
y
que satisfaga la ecuación anterior.El código
El truco que he mencionado a una mejor prueba del código, se colocan nuevamente
rand()&&
conrand()%2&&
de manera que hay una probabilidad de 50-50 que cualquier dado y se pasa por alto, en lugar de un 1 en laRAND_MAX
posibilidad de que se utilice cualquier Y dado.fuente
p(y),x-=y++)while(rand()&&(i-n)*((~n+i)/2+~y)+y<x)y++;
lugar de){while(rand()&&(n-i)*(n-i+1)/2+(n-i)*(y+1)+y<x)y++;p(y);x-=y++;}
Limpio , 172 bytes
Pruébalo en línea!
fuente
Python (2 o 3), 84 bytes
Pruébalo en línea!
Golpea la profundidad máxima de recursión alrededor de l (5)
fuente
Kotlin , 32 bytes
Pruébalo en línea!
fuente
Mathematica 40 bytes
fuente
RandomChoice@IntegerPartitions[#^2,{#}]&
Wolfram Language (Mathematica) , 49 bytes
Pruébalo en línea!
Versión golfizada por @ J42161217.
Wolfram Language (Mathematica) , 62 bytes
Pruébalo en línea!
Cómo funciona
La respuesta a la tarea de bonificación
que es, en Mathematica:
Pruébalo en línea!
fuente
(While[Tr[s=RandomSample[Range[#^2],#]]!=#^2];s)&