Lorsque vous empilez des livres, vous devez généralement placer les plus grands en bas et les plus petits en haut. Cependant, mon TOC latent me met très mal à l'aise si j'ai deux livres où l'un est plus court (en hauteur) mais plus large que l'autre. Peu importe l'ordre dans lequel je les place, le livre supérieur s'étendra au-delà du livre inférieur d'un côté.
Par exemple, disons qu'un livre a des dimensions (10,15)
et un autre a des dimensions (11,14)
. Peu importe où je les mets, j'obtiens un surplomb. Mais si j'ai des livres avec des dimensions (4,3)
et (5,6)
, je peux éviter un surplomb en plaçant ces derniers en dessous des premiers.
Aux fins de ce défi, nous ne considérerons les surplombs que par rapport au livre immédiatement ci-dessous . Par exemple , si j'ai une pile (5,5)
, (3,3)
, (4,4)
(pas que toute personne saine d' esprit ferait cela), les chefs de livre en haut comme un surplomb, même si elle ne dépasse pas le livre de fond. De même, la pile (3,3)
, (3,3)
, (4,4)
a aussi un seul faux, malgré le livre de haut qui dépasse celui du bas.
Le défi
Étant donné une liste de paires entières pour les dimensions du livre, triez ces paires / livres de sorte que le nombre de porte-à-faux soit minimal. Vous ne devez pas faire tourner les livres - je veux que toutes les épines soient orientées dans la même direction. S'il existe plusieurs solutions avec le même nombre de porte-à-faux, vous pouvez choisir une telle commande. Votre algorithme de tri n'a pas besoin d'être stable. Votre implémentation peut supposer que les dimensions du livre sont inférieures à 2 16 chacune.
Complexité temporelle: pour rendre cela un peu plus intéressant, la complexité asymptotique du pire des cas de votre algorithme doit être polynomiale dans la taille de la pile. Vous ne pouvez donc pas simplement tester toutes les permutations possibles. Veuillez inclure une courte preuve de l'optimalité et de la complexité de votre algorithme et éventuellement un tracé qui montre la mise à l'échelle pour les grandes entrées aléatoires. Bien sûr, vous ne pouvez pas utiliser la taille maximale de l'entrée comme argument que votre code s'exécute dans O (1).
Vous pouvez écrire un programme ou une fonction, saisir des données via STDIN, ARGV ou un argument de fonction dans n'importe quel format de liste pratique (non prétraité) et imprimer ou renvoyer le résultat.
Il s'agit du code golf, donc la réponse la plus courte (en octets) l'emporte.
Je suis convaincu qu'il existe une solution polynomiale, mais si vous pouvez me prouver le contraire, vous pouvez soumettre une telle preuve au lieu d'une soumission golfée. Dans ce cas, vous pouvez supposer P ≠ NP . J'accepterai la première bonne preuve et je lui accorderai une prime.
Exemples
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]]
Je les ai créés à la main, alors faites-moi savoir si vous repérez des erreurs.
la source
Réponses:
Pyth , 30
Ceci est un golf direct de l'algorithme génial de grc. Voici l'équivalent précis du programme pyth ci-dessus, dans son code python compilé.
Dans ce contexte, la
Psum(Y)
fonction est équivalente au pythonsum(Y,[])
.Code réel compilé et exécuté (à partir de
pyth -d
):la source
sum(Y,[])
. Tout cela devrait fonctionner en Pyth, juste la traduction ne l'inclut pas automatiquement.Pprint("\n",Psum(Y))
. Je pense qu'il a peut - être simplifié pour la commodité, ainsi que tous les-1
s , etc.Psum
serait en fait fonctionner plus commereduce(lambda x,y:x+y, Y[1:], Y[0])
.Python, 113
Après avoir trié la liste des livres par ordre décroissant (d'abord en largeur puis en hauteur), cela partitionne les livres en piles sans chevauchements. Pour déterminer où placer chaque livre, sa hauteur est comparée à la hauteur du livre supérieur dans chaque pile. Il est placé sur la première pile possible, sinon une nouvelle pile est créée.
Je ne suis pas très bon avec la complexité du temps, mais je pense qu'il aurait un pire cas de O ( N 2 ). Il y a deux boucles, chacune avec au plus N itérations. J'utilise également le tri intégré de Python, qui est O ( n log n ).
Ma première preuve que cet algorithme produit des solutions optimales s'est avérée incorrecte. Un grand merci va à @xnor et @ Sp3000 pour une grande discussion dans le chat sur la preuve de cela (que vous pouvez lire en commençant ici ). Après avoir élaboré une preuve correcte, @xnor a constaté qu'une partie de celle-ci avait déjà été effectuée ( théorème de Dilworth ).
Voici tout de même un aperçu de la preuve (crédit à @xnor et @ Sp3000).
Tout d'abord, nous définissons la notion d'antipile, ou antichain, ( citée de @xnor ):
Ensuite, nous trions les livres par ordre décroissant selon leur largeur (première) et leur hauteur (seconde) *.
Pour chaque livre B , nous procédons comme suit:
Maintenant, nous avons construit un lien à partir de chaque livre (sauf ceux de la première pile), vers un livre de la pile précédente qui est plus large et moins haut.
L'excellent diagramme de @ Sp3000 illustre bien cela:
En suivant n'importe quel chemin de la dernière pile (à droite), à la première pile (à gauche), nous obtenons un antipile. Surtout, la longueur de cet antipile est égale au nombre de piles. Par conséquent, le nombre de piles utilisées est minime.
Enfin, puisque nous avons organisé les livres en un nombre minimum de piles sans chevauchements, nous pouvons les empiler les uns sur les autres pour obtenir une pile avec le nombre minimum de chevauchements.
* ce commentaire utile explique quelques choses
la source