Al apilar libros, generalmente desea colocar los más grandes en la parte inferior y los más pequeños en la parte superior. Sin embargo, mi TOC latente me hace sentir muy incómodo si tengo dos libros donde uno es más corto (en altura) pero más ancho que el otro. No importa en qué orden los coloque, el libro superior se extenderá más allá del libro inferior en un lado.
Como ejemplo, digamos que un libro tiene dimensiones (10,15)
y otro tiene dimensiones (11,14)
. No importa en qué dirección los coloque, me sale un saliente. Pero si tengo libros con dimensiones (4,3)
y (5,6)
, puedo evitar sobresalir colocando el último debajo del primero.
A los fines de este desafío, consideraremos los voladizos solo en relación con el libro que se encuentra a continuación . Por ejemplo, si tengo una pila (5,5)
, (3,3)
, (4,4)
(no es que cualquier persona sana haría eso), los recuentos de libros como un voladizo superior, a pesar de que no se extiende más allá del libro de fondo. Del mismo modo, la pila (3,3)
, (3,3)
, (4,4)
también tiene sólo un voladizo, a pesar del libro superior que se extiende más allá de la parte inferior.
El reto
Dada una lista de pares enteros para las dimensiones de los libros, clasifique esos pares / libros de modo que el número de voladizos sea mínimo. No debe rotar los libros: quiero que todas las espinas estén orientadas en la misma dirección. Si hay varias soluciones con el mismo número de voladizos, puede elegir cualquier orden. Su algoritmo de clasificación no tiene que ser estable. Su implementación puede suponer que las dimensiones del libro son inferiores a 2 16 cada una.
Complejidad del tiempo: para hacer esto un poco más interesante, la complejidad asintótica del peor de los casos de su algoritmo debe ser polinomial en el tamaño de la pila. Por lo tanto, no puede probar cada permutación posible. Incluya una breve prueba de la optimización y complejidad de su algoritmo y, opcionalmente, un gráfico que muestre la escala para entradas aleatorias grandes. Por supuesto, no puede usar el tamaño máximo de la entrada como argumento de que su código se ejecuta en O (1).
Puede escribir un programa o función, recibir información a través de STDIN, ARGV o argumento de función en cualquier formato de lista conveniente (no preprocesado) e imprimir o devolver el resultado.
Este es el código de golf, por lo que gana la respuesta más corta (en bytes).
Estoy seguro de que existe una solución polinómica, pero si puede demostrar que estoy equivocado, puede presentar dicha prueba en lugar de una presentación de golf. En este caso, puede suponer P ≠ NP . Aceptaré la primera prueba correcta y le otorgaré una recompensa.
Ejemplos
In: [[1, 1], [10, 10], [4, 5], [7, 5], [7, 7], [10, 10], [9, 8], [7, 5], [7, 5], [3, 1]]
Out: [[10, 10], [10, 10], [9, 8], [7, 7], [7, 5], [7, 5], [7, 5], [4, 5], [3, 1], [1, 1]]
In: [[4, 5], [5, 4], [5, 4], [5, 4], [5, 4], [4, 5], [4, 5], [4, 5], [5, 4], [4, 5]]
Out: [[4, 5], [4, 5], [4, 5], [4, 5], [4, 5], [5, 4], [5, 4], [5, 4], [5, 4], [5, 4]]
or [[5, 4], [5, 4], [5, 4], [5, 4], [5, 4], [4, 5], [4, 5], [4, 5], [4, 5], [4, 5]]
In: [[2, 3], [1, 1], [5, 5], [7, 1]]
Out: [[5, 5], [2, 3], [7, 1], [1, 1]]
or [[5, 5], [2, 3], [1, 1], [7, 1]]
or [[7, 1], [5, 5], [2, 3], [1, 1]]
or [[7, 1], [1, 1], [5, 5], [2, 3]]
Los creé a mano, así que avísame si ves algún error.
fuente
Respuestas:
Pyth , 30
Este es un campo directo del asombroso algoritmo de GRC. Aquí está el equivalente preciso del programa pyth anterior, en su código compilado de python.
En este contexto, la
Psum(Y)
función es equivalente a la pitónsum(Y,[])
.Código compilado y ejecutado real (desde
pyth -d
):fuente
sum(Y,[])
. Todo esto debería funcionar en Pyth, solo la traducción no lo incluye automáticamente.Pprint("\n",Psum(Y))
. Creo que puede haberlo simplificado por conveniencia, junto con todos los-1
s, etc., enPsum
realidad funcionarían másreduce(lambda x,y:x+y, Y[1:], Y[0])
.Python, 113
Después de ordenar la lista de libros en orden descendente (primero por ancho y luego por altura), esto divide los libros en pilas sin superposiciones. Para determinar dónde colocar cada libro, su altura se compara con la altura del libro superior en cada pila. Se coloca en la primera pila posible, o se crea una nueva pila.
No soy muy bueno con la complejidad del tiempo, pero creo que sería el peor de los casos de O ( N 2 ). Hay dos bucles, cada uno con N iteraciones como máximo . También uso el tipo integrado de Python, que es O ( n log n ).
Mi primera prueba de que este algoritmo produce soluciones óptimas resultó ser incorrecta. Un gran agradecimiento a @xnor y @ Sp3000 por una gran discusión en el chat sobre probar esto (que puedes leer comenzando aquí ). Después de elaborar una prueba correcta, @xnor descubrió que parte de ella ya se había hecho ( teorema de Dilworth ).
Aquí hay una descripción general de la prueba de todos modos (crédito a @xnor y @ Sp3000).
Primero, definimos la noción de un antipile o antichain ( citado de @xnor ):
Luego, clasificamos los libros en orden descendente por su ancho (primero) y su altura (segundo) *.
Para cada libro B , hacemos lo siguiente:
Ahora, hemos construido un enlace de cada libro (excepto los de la primera pila), a un libro en la pila anterior que es mayor en ancho y menor en altura.
El excelente diagrama de @ Sp3000 ilustra esto bien:
Al seguir cualquier camino desde el último montón (a la derecha), hasta el primer montón (a la izquierda), obtenemos un antipile. Es importante destacar que la longitud de este antipile es igual al número de pilas. Por lo tanto, el número de pilas utilizadas es mínimo.
Finalmente, dado que hemos organizado los libros en la cantidad mínima de pilas sin superposiciones, podemos apilarlas una encima de la otra para obtener una pila con la cantidad mínima de superposiciones.
* este útil comentario explica algunas cosas
fuente