Primero, algunas definiciones:
- Dado
n
yk
, considere la lista ordenada de conjuntos múltiples , donde para cada conjunto múltiple elegimosk
números{0, 1, ..., n-1}
con repeticiones.
Por ejemplo, para n=5
y k=3
, tenemos:
[(0, 0, 0), (0, 0, 1), (0, 0, 2), (0, 0, 3), (0, 0, 4), (0, 1, 1), ( 0, 1, 2), (0, 1, 3), (0, 1, 4), (0, 2, 2), (0, 2, 3), (0, 2, 4), (0, 3, 3), (0, 3, 4), (0, 4, 4), (1, 1, 1), (1, 1, 2), (1, 1, 3), (1, 1, 4), (1, 2, 2), (1, 2, 3), (1, 2, 4), (1, 3, 3), (1, 3, 4), (1, 4, 4) , (2, 2, 2), (2, 2, 3), (2, 2, 4), (2, 3, 3), (2, 3, 4), (2, 4, 4), ( 3, 3, 3), (3, 3, 4), (3, 4, 4), (4, 4, 4)]
- Una parte es una lista de conjuntos múltiples con la propiedad de que el tamaño de la intersección de todos los conjuntos múltiples en la parte es al menos
k-1
. Es decir, tomamos todos los conjuntos múltiples y los intersectamos (usando la intersección de conjuntos múltiples) de una vez. Como ejemplos,[(1, 2, 2), (1, 2, 3), (1, 2, 4)]
es una parte ya que su intersección es de tamaño 2, pero[(1, 1, 3),(1, 2, 3),(1, 2, 4)]
no lo es, porque su intersección es de tamaño 1.
Tarea
Su código debe tomar dos argumentos n
y k
. A continuación, debe pasar con avidez por estos conjuntos múltiples en orden ordenado y generar las partes de la lista. Para el caso n=5, k=3
, la partición correcta es:
(0, 0, 0), (0, 0, 1), (0, 0, 2), (0, 0, 3), (0, 0, 4)
(0, 1, 1), (0, 1, 2), (0, 1, 3), (0, 1, 4)
(0, 2, 2), (0, 2, 3), (0, 2, 4)
(0, 3, 3), (0, 3, 4)
(0, 4, 4)
(1, 1, 1), (1, 1, 2), (1, 1, 3), (1, 1, 4)
(1, 2, 2), (1, 2, 3), (1, 2, 4)
(1, 3, 3), (1, 3, 4)
(1, 4, 4)
(2, 2, 2), (2, 2, 3), (2, 2, 4)
(2, 3, 3), (2, 3, 4)
(2, 4, 4)
(3, 3, 3), (3, 3, 4)
(3, 4, 4), (4, 4, 4)
Aquí hay otro ejemplo para n = 4, k = 4
.
(0, 0, 0, 0), (0, 0, 0, 1), (0, 0, 0, 2), (0, 0, 0, 3)
(0, 0, 1, 1), (0, 0, 1, 2), (0, 0, 1, 3)
(0, 0, 2, 2), (0, 0, 2, 3)
(0, 0, 3, 3)
(0, 1, 1, 1), (0, 1, 1, 2), (0, 1, 1, 3)
(0, 1, 2, 2), (0, 1, 2, 3)
(0, 1, 3, 3)
(0, 2, 2, 2), (0, 2, 2, 3)
(0, 2, 3, 3), (0, 3, 3, 3)
(1, 1, 1, 1), (1, 1, 1, 2), (1, 1, 1, 3)
(1, 1, 2, 2), (1, 1, 2, 3)
(1, 1, 3, 3)
(1, 2, 2, 2), (1, 2, 2, 3)
(1, 2, 3, 3), (1, 3, 3, 3)
(2, 2, 2, 2), (2, 2, 2, 3)
(2, 2, 3, 3), (2, 3, 3, 3)
(3, 3, 3, 3)
Aclaración de lo que significa codicioso: para cada conjunto múltiple, a su vez, buscamos si se puede agregar a la parte existente. Si puede, lo añadimos. Si no puede, comenzamos una nueva parte. Observamos los conjuntos múltiples en orden ordenado como en el ejemplo dado anteriormente.
Salida
Puede generar la partición en cualquier formato sensible que desee. Sin embargo, los conjuntos múltiples deben escribirse horizontalmente en una línea. Es un conjunto múltiple individual que no debe escribirse verticalmente ni distribuirse en varias líneas. Puede elegir cómo separar la representación de las partes en la salida.
Supuestos
Podemos suponer eso n >= k > 0
.
fuente
(0, 4, 4)
por qué está solo? Dada su descripción, creo que su "parte" sería(0, 4, 4), (1, 4, 4), (2, 4, 4), (3, 4, 4), (4, 4, 4)
. Del mismo modo para(0, 0, 3, 3)
en el segundo caso de prueba.Respuestas:
Jalea ,
2625 bytesPrograma completo que imprime una representación de una lista de listas, cada una de las cuales es una parte, por ejemplo, para n = 5, k = 3:
Nota: la representación utilizada elimina las listas redundantes
[
y]
redondas de longitud 1.Pruébalo en línea! o vea una bonita versión impresa (costo 3 bytes)
¿Cómo?
fuente
MATLAB, 272 bytes
Salida:
Dos líneas vacías entre diferentes partes.
Sin golf:
Explicación:
Primero encontramos todos los multisets con fuerza bruta:
repmat(0:n-1, 1, k)
repite el vector de valores de0
an-1
k
veces.nchoosek(x, k)
devuelve una matriz que contiene todas las combinaciones k del vector repetido.sort(x, 2)
ordena todas las combinaciones de k y luegounique(x, 'rows')
elimina todos los duplicados.p=zeros(0,k);
crea una matriz vacía conk
columnas. Lo usaremos como una pila. En cada iteración del outernmostfor
bucle, primero agregamos el conjunto múltiple de corriente a dicha pila:p=[p;l(i,:)];
.Luego verificamos si la intersección de todos los conjuntos múltiples en la pila es al menos
k-1
larga con el siguiente código (no podemos usar elintersect
comando de MATLAB para verificar las intersecciones, porque devuelve un conjunto, pero necesitamos un conjunto múltiple):Ahora, si la intersección es lo suficientemente larga
a == 0
, de lo contrarioa == 1
.Si la intersección no es lo suficientemente larga, imprimimos una nueva línea y vaciamos la pila:
Luego simplemente imprimimos el multiset actual:
fuente
MATL , 34 bytes
Las partes están separadas por una línea que contiene espacios en blanco.
Pruébalo en línea!
Explicación
Descargo de responsabilidad: este método parece funcionar (y funciona en los casos de prueba), pero no tengo pruebas de que siempre funcione
Los conjuntos múltiples se ordenan, tanto internamente (es decir, cada conjunto múltiple tiene entradas que no disminuyen) como externamente (es decir, el conjunto múltiple M viene antes del conjunto múltiple N si M precede a N lexicográficamente).
Para calcular la intersección de múltiples conjuntos, los múltiples conjuntos ordenados se ordenan como filas de una matriz y se calculan las diferencias consecutivas a lo largo de cada columna. Si todas las columnas, excepto como máximo una, tienen todas las diferencias iguales a cero, los conjuntos múltiples pertenecen a la misma parte.
Esta prueba daría un resultado falso negativo para multisets como
(1,2,3)
y(2,3,4)
: incluso si2
,3
son entradas comunes, que no serían detectados como tales porque están en columnas no coincidentes.Sin embargo, esto no parece ser un problema, al menos en los casos de prueba. Parece que una prueba entre múltiples conjuntos gusta
1,2,3
y2,3,4
nunca tiene que hacerse, porque algunos conjuntos múltiples intermedios dieron un resultado negativo y, por lo tanto, ya están en diferentes partes. Si esto es cierto, la razón sin duda tiene que ver con el hecho de que los multisets están ordenados.Sin embargo, no tengo una prueba de esto. Simplemente parece funcionar.
fuente
n=k=4
caso de que comencemos con una nueva parte(0, 0, 3, 3)
, la diferencia consecutiva vectorizada de eso y el conjunto múltiple anterior(0, 0, 2, 3)
solo tiene una diferencia, entonces, ¿cómo hace que la "parte hasta ahora" funcione? (o equivalente, ¿cuál fue el resultado del paso anterior que se usó en lugar de(0, 0, 2, 3)
?)PHP, 245 bytes
Pruébalo en línea!
Expandido
Salida como cadena
n> 15 para mayor precisión
fuente
0
para(16**16-1)%16
y el tiempo de trabajo sólo en la versión con la precisión que se necesita paran>15
bcmod(bcsub(bcpow(16,16),1),16)
es15
php.net/manual/en/ref.bc.php