Considere una variedad A
de longitud n
. La matriz contiene solo enteros positivos. Por ejemplo A = (1,1,2,2)
. Definamos f(A)
como el conjunto de sumas de todos los subconjuntos contiguos no vacíos de A
. En este caso f(A) = {1,2,3,4,5,6}
. Los pasos para producir f(A)
son los siguientes:
Las submatrices de A
son (1), (1), (2), (2), (1,1), (1,2), (2,2), (1,1,2), (1,2,2), (1,1,2,2)
. Sus sumas respectivas son 1,1,2,2,2,3,4,4,5,6
. El conjunto que obtienes de esta lista es por lo tanto {1,2,3,4,5,6}
.
Tarea
Dado un conjunto de sumas S
dadas en orden ordenado que contiene solo enteros positivos y una longitud de matriz n
, su tarea es generar al menos una matriz de X
tal manera f(X) = S
.
Por ejemplo, si S = {1,2,3,5,6}
y n = 3
luego es una salida válida X = (1,2,3)
.
Si no existe dicha matriz, X
su código debería generar un valor constante.
Ejemplos
Entrada: n=4, S = (1, 3, 4, 5, 6, 8, 9, 10, 13)
salida posible:X = (3, 5, 1, 4)
Entrada: n=6, S = (2, 3, 4, 5, 7, 8, 9, 10, 12, 14, 17, 22)
salida posible:X = (5, 3, 2, 2, 5, 5)
Entrada: n=6, S = (2, 4, 6, 8, 10, 12, 16)
salida posible:X = (4, 2, 2, 2, 2, 4)
Entrada: n=6, S = (1, 2, 3, 4, 6, 7, 8, 10, 14)
salida posible:X = (4, 2, 1, 1, 2, 4)
Entrada: n=10, S = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 17, 18, 19, 20, 23, 24, 25)
, posible salida: X = (1, 1, 3, 1, 2, 1, 2, 5, 4, 5)
.
Entrada: n=15, S = (1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, 26, 27, 28, 30, 31)
, posible salida: X = (1, 2, 1, 3, 3, 1, 3, 3, 1, 3, 3, 1, 2, 1, 3)
.
Formato de entrada y salida.
Su código puede recibir entrada y salida en cualquier formato de lectura humana que le resulte conveniente. Sin embargo, muestre el resultado de probarlo en los ejemplos de la pregunta.
Tiempo de ejecución
Debe poder ejecutar el código hasta su finalización para todos los ejemplos en la pregunta. En principio, debería ser correcto n
, 15
pero no es necesario demostrar que sería lo suficientemente rápido para todas las entradas.
Respuestas:
Casco , 20 bytes
Pruébalo en línea!
Devuelve una solución o una lista vacía si no existe. El último caso de prueba (
n=15
) termina en 3.8 segundos en TIO.Explicación
El programa tiene dos partes. En la primera parte (
¡
y a la derecha de la misma), construimos una lista infinita cuyok
elemento th es una lista que contiene todas lask
listas de longitud cuyas sumas de corte están incluidasS
. Hacemos esto inductivamente, comenzando desde los segmentos de 1 elementoS
y, en cada paso, anteponiendo cada elemento deS
a cada lista, y manteniendo aquellos cuyas sumas de prefijo están enS
. En la segunda parte (!
ya la izquierda de la misma), tomamos eln
elemento th de la lista, que contienen
listas de longitud . De estos, seleccionamos el primero cuyas sumas de corte contienen cada elemento deS
.En el código, primero reemplacemos
o
yȯ
(que componen dos y tres funciones en una) por paréntesis para mayor claridad.Hay algunas partes que necesitan más explicación. En este programa, los superíndices se
⁰¹
refieren al primer argumentoS
. Sin embargo, siα
es una función,α¹
significa "aplicarα
aS
", mientras que⁰α
significa "conectarS
al segundo argumento deα
". La función¦
verifica si su primer argumento contiene todos los elementos del segundo (contando multiplicidades), por lo queS
debería ser su segundo argumento.En la primera parte, la función que
¡
utiliza se puede interpretar comoS(f~Λ€∫)(×:)¹
. El combinador seS
comporta comoSαβγ -> (αγ)(βγ)
, lo que significa que podemos simplificarlo(f~Λ€∫¹)(×:¹)
. La segunda parte,×:¹
es "mezclar conS
anteponer", y su resultado se pasa a la primera parte. La primera partef~Λ€∫¹
, funciona así. La funciónf
filtra una lista por una condición, que en este caso es~Λ€∫¹
. Recibe una lista de listasL
, por lo que tenemos~Λ€∫¹L
. El combinador se~
comporta como~αβγδε -> α(βδ)(γε)
: el primer argumento se pasa aβ
, el segundo aγ
, y los resultados se combinan conα
. Esto significa que tenemosΛ(€¹)(∫L)
. La última parte∫L
son solo las sumas acumuladas deL
,€¹
es una función que registra la membresíaS
yΛ
toma una condición (aqu퀹
) y una lista (aquí∫L
), y verifica que todos los elementos la satisfagan. En pocas palabras, filtramos los resultados de la mezcla según si todas las sumas acumulativas están incluidasS
.fuente
Ruby , 135 bytes
Pruébalo en línea!
Use una búsqueda de amplitud. n = 10 funciona en TIO, n = 15 lleva más de un minuto, pero funciona en mi máquina.
Rubí , 147 bytes
Pruébalo en línea!
Versión optimizada, funciona en TIO para n = 15 (~ 20 segundos)
En realidad, este es el comienzo de un enfoque de fuerza no bruta. Espero que alguien trabaje en ello y encuentre una solución completa.
Primeras ideas:
Lo que nos lleva a la próxima optimización:
Ruby , 175 bytes
Pruébalo en línea!
~ 8.5 segundos en TIO. No está mal...
... y así sucesivamente (para ser implementado)
fuente
Haskell,
117111bytes¡6 bytes guardados gracias a @nimi!
Pruébalo en línea!
f
r
i
n
s
Cuando
n
es cero (golfedn<1
) la lista debe estar lista, por lo que verificamos si se han visto todos los valores. Si no, devolvemos una lista vacía para indicar que no hay soluciones, de lo contrario, devolvemos una lista singleton que contiene una lista vacía, a la que se agregarán los elementos elegidos. Este caso también podría haberse manejado con las ecuaciones adicionalesSi
n
no es cero, volvemosEsta es la lista de (1) listas de donde proviene el primer elemento (2)
s
y el resto (5) proviene de la llamada recursiva, bajo la condición (4) de que se encuentran todas las sumas nuevass
. Las nuevas sumas se calculan en (3): tenga en cuenta quet
se extrae de una lista única, un truco de golf feo para lo que en el idiomático de Haskell seríalet t=y:map(y+)i
. La llamada recursiva (5) obtiene como nuevor
conjunto el antiguo sin esos elementos que aparecen entre las nuevas sumast
.La función principal
&
llama a la función auxiliar diciendo que todavía tenemos que ver todos los valores (r=s
) y que todavía no hay sumas (i=[]
).Para siete bytes más, podemos restringir el cálculo para dar solo el primer resultado (si lo hay), que es mucho más rápido y maneja todos los casos de prueba en menos de 2 segundos.
Pruébalo en línea! (este es el primer resultado solo variación de la versión anterior)
fuente
map
, solo lo intenté,<$>
pero eso necesitaba padres adicionales ... @Anush No tengo idea de una solución de tiempo polinomialLimpio , 177 bytes
Pruébalo en línea!
Toma alrededor de 40 segundos en mi máquina para el
n=15
caso de prueba, pero se agota en TIO.Limpio , 297 bytes
Pruébalo en línea!
Este incluye algunas optimizaciones hechas por GB , así como algunas mías. Creo que algunos de ellos pueden hacerse más genéricos, por lo que agregaré una explicación una vez que haya terminado.
Tarda unos 10 segundos en mi máquina, 40 segundos en TIO.
fuente
@mention
mañana cuando estén despiertos, lamentablemente no tengo tiempo hoy.Python 3 , 177 bytes
Pruébalo en línea!
(se agregaron algunas líneas / espacios nuevos para evitar que los lectores tengan que desplazarse por el código)
Un puerto directo de mi respuesta Jelly (con algunas modificaciones, consulte la sección "nota" a continuación)
Resultado de ejecución local:
Escuché que
itertools
es detallado, pero mi mejorcombinations
implementación es aún más detallada:Nota .
a[p//n:p%n+1]
toma aproximadamente 2 veces más, pero ahorra algunos bytes.combinations
devolver un iterador, esto es más amigable con la memoria.fuente
Jalea , 35 bytes
Pruébalo en línea!
Ejecutar localmente: (n = 15 requiere más de 1 GB de RAM)
(en realidad ejecuté la versión codificada en UTF8, que toma más de 35 bytes, pero el resultado es el mismo de todos modos)
Esta solución utiliza cortocircuito para reducir el tiempo de ejecución.
Explicación
Observamos que las sumas de todos los prefijos no vacíos están presentes en la entrada y están aumentando estrictamente. También podemos suponer que el elemento más grande y el segundo más grande es una suma de prefijo.
No probado (pero debe tener un rendimiento idéntico)
Jalea , 32 bytes
Pruébalo en línea!
Versión más ineficiente (sin cortocircuito):
Jalea , 27 bytes
Pruébalo en línea!
Para la prueba n = 15, toma hasta 2 GB de RAM y no termina después de ~ 37 minutos.
nota :
Ẇ§
puede ser reemplazado conÄÐƤẎ
. Puede ser más eficiente.fuente
APL (NARS), caracteres 758, bytes 1516
La función G en G x (con la ayuda de la función H) encontraría todas las permutaciones de x. La función d en xdy busca si la matriz y se genera siguiendo la matriz de ejercicios x que devuelve un valor booleano. La función F en x F y devolvería la matriz r de longitud x, de modo que ydr es verdadero (= 1) Un poco más largo que la implementación, pero es este el que calcula todos los casos en la prueba menos tiempo ... El último caso para n = 15 se ejecuta solo 20 segundos ... tengo que decir que no encuentra muchas soluciones, devuelve solo una solución (por fin parece) en menos tiempo (prueba no explorada para diferentes entradas ...) 16 + 39 + 42 + 8 + 11 + 11 + 18 + 24 + 24 + 54 + 11 + 12 + 7 + 45 + 79 + 69 + 12 + 38 + 26 + 72 + 79 + 27 + 15 + 6 + 13 (758)
fuente