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 nenteros exactamente aleatorios entre 1e 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:2negocio es evitar la forma extraña desampleactuar cuando el primer argumento tiene longitud 1.fuente
pdirectamente 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í querepsolo garantiza que esto nunca sucederá. Puede haber una mejor manera, pero esto fue rápido y estaba enojadosample.x*!!1:2overrep(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=1a 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+1que contiene:0,ncuadrado, yn-1cantidad de números enteros aleatorios en el rango de[0, n squared)2) Ordenar esta matriz
3) Crear una segunda matriz de tamaño
nque contiene las diferencias hacia adelante de paresEstos tres primeros pasos nos darán una matriz que contiene
nal azar enteros (en el rango[0, n squared)que suma alncuadrado.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 inicio0y 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.do 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=1es 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⍵*2cuadrar el argumentos←asignar as(para s quare)⍵?encuentreníndices aleatorios de 1 ...ssin reemplazoc←asignar ac(para c andidate)+/sumaloss=comparar cons:si es igualcdevolver 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≢?≢×≢elijanenteros al azar distintos entre 1 yn2+.-∘≢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.nes una constante, pero desafortunadamente ambassyr.size()son variables que pueden ser tanto inferiores como superiores0ynrespectivamente.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, cortenelementos de la matriz. Mientras que la suma de los elementos aleatorios no es igual a lan^2matriz de bucle de elementos aleatorios; si la suma de los elementos de la matriz es mayor que eln^2elemento actual-1no es igual a cero o el elemento actual-1no está en la matriz actual, reste1; si la suma de la matriz es menor quen^2y el elemento actual+1no está en la matriz, agregue1al elemento. Si la suma de la matriz es igual an^2romper el bucle, la matriz de salida.fuente
k++whilebucles 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..elsedeclaraciones; entre otras partes del código que probablemente podrían ajustarse para el golf; ieg, eliminandoletdeclaraciones.if..elsen?" . probando resultado esperado si el algoritmo devuelve constantemente paran^2arrays 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
nnú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.
xkyxNo obstante, la lógica es tener la oportunidad de descartar cualquiera
yque 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_MAXposibilidad 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)&