Primero, algunas definiciones:
- Dado
nyk, considere la lista ordenada de conjuntos múltiples , donde para cada conjunto múltiple elegimosknúmeros{0, 1, ..., n-1}con repeticiones.
Por ejemplo, para n=5y 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 ny 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 de0an-1kveces.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 conkcolumnas. Lo usaremos como una pila. En cada iteración del outernmostforbucle, 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-1larga con el siguiente código (no podemos usar elintersectcomando 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,3son 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,3y2,3,4nunca 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=4caso 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
0para(16**16-1)%16y el tiempo de trabajo sólo en la versión con la precisión que se necesita paran>15bcmod(bcsub(bcpow(16,16),1),16)es15php.net/manual/en/ref.bc.php