Écrivez une fonction / sous-routine pour trier une liste d'entiers, style Tour de Hanoi .
Vous recevrez une pile d'entiers. Ceci est la pile principale.
Vous disposez également de deux piles d'aide supplémentaires. Ces piles d'assistance ont cependant une propriété unique: chaque élément doit être plus petit ou de la même taille que l'élément en dessous. La pile principale n'a pas une telle restriction.
Vous êtes chargé de trier la pile principale en place, en plaçant les plus grands entiers en dessous. Votre fonction / sous-programme renverra (ou équivalent) le nombre de mouvements effectués lors du tri de la pile.
Remarque: vous devez trier la pile principale en place , pas de tri sur une autre pile et appeler cela la réponse. Cependant, si pour une raison quelconque vous ne pouvez pas le faire, vous pouvez simuler les piles modifiables, mais rappelez-vous qu'il s'agit du type Tour de Hanoi; il n'y a que 3 chevilles et une seule cheville peut être désordonnée.
Votre fonction / sous-routine peut inspecter n'importe quelle pile à tout moment, mais elle ne peut faire un mouvement qu'en sautant et en poussant. Un seul coup est un pop d'une pile qui est poussé à l'autre.
Testez votre fonction / sous-routine pour chaque permutation des 6 premiers nombres naturels. En d'autres termes, testez votre fonction / sous-programme {1},{2},...,{6},{1,1},{1,2},...,{1,6},{2,1},...
(cela devrait être un total de ou des possibilités (merci à Howard d'avoir corrigé mes calculs)). La fonction / sous-routine qui déplace les éléments le moins de fois gagne.61+62+...+66
55986
la source
6**1+6**2+...+6**6=55986
éléments.Réponses:
Java - solution optimale (1080544 coups)
Cette solution crée un arbre de chemin le plus court à partir de la cible et vers l'arrière, puis parcourt le chemin de l'état initial à la cible. Beaucoup de place pour l'amélioration de la vitesse, mais cela résout toujours tous les problèmes 55986 en une minute environ.
En supposant que l'algorithme est correctement implémenté, cela devrait être la meilleure solution théoriquement.
la source
C - 2547172 pour 55986 entrées
Il y a beaucoup de place à l'amélioration ici. Pour ma propre raison, j'ai simplifié cela afin qu'il ne soit possible d'inspecter que l'élément supérieur de chaque pile. La levée de cette restriction auto-imposée permettrait des optimisations telles que la détermination de l'ordre final à l'avance et la tentative de minimiser le nombre de mouvements nécessaires pour y parvenir. Un exemple convaincant est que mon implémentation a le pire des cas si la pile principale est déjà triée.
Algorithme:
Une analyse:
la source
Python,
39838383912258 se déplace sur 55986 entréesC'est très inefficace.
J'ajouterai le nombre total de mouvements après que le PO clarifie s'il s'agit de tous ces cas ou d'autres cas spécifiques.
Explication
Quoi, des commentaires qui ne vous conviennent pas?
Note à OP: Merci de ne pas avoir fait ce code-golf.
la source
[2,1,1]
existe-t-il un moyen d'en obtenir[2,1,1].index(1)
2, c'est-à-dire en partant de l'extrémité supérieure?[2,1,1,3,5].index(1)==2
au lieu de1
list.index(data)
renvoie l'index de l'élémentdata
danslist
. Je ne connais pas l'indice dedata
ie1
len(list)-(list[::-1].index(1))
Python:
1.688.2931.579.1821.524.0541.450.8421.093.195 mouvementsLa méthode principale consiste
main_to_help_best
à déplacer certains éléments sélectionnés de la pile principale vers la pile d'assistance. Il a un drapeaueverything
qui définit si nous voulons qu'il déplace tout dans le spécifiédestination
, ou si nous voulons garder uniquement le plus grand dansdestination
le reste dans l'autre assistant.En supposant que nous passons à l'
dst
aide de l'aidehelper
, la fonction peut être décrite comme suit:helper
récursivementdst
helper
à principaldst
everything
est défini, déplacez récursivement les éléments du principal versdst
b. Sinon, déplacez récursivement les éléments principaux vers
helper
L'algorithme de tri principal (
sort2
dans mon code) appellera ensuitemain_to_help_best
aveceverything
set toFalse
, puis ramènera le plus grand élément vers main, puis déplacera tout de l'assistant vers main, le gardant trié.Plus d'explications intégrées sous forme de commentaires dans le code.
Fondamentalement, les principes que j'ai utilisés sont:
Le principe 3 est implémenté en ne comptant pas le mouvement si la source est la destination précédente (c'est-à-dire que nous venons de déplacer principal vers help1, puis nous voulons passer de help1 à help2), et de plus, nous réduisons le nombre de mouvements de 1 si nous le ramène à sa position d'origine (c.-à-d. principal pour aider1 puis aide1 pour principal). De plus, si les
n
mouvements précédents déplacent tous le même entier, nous pouvons réellement réorganiser cesn
mouvements. Nous en profitons donc également pour réduire encore le nombre de mouvements.Ceci est valable car nous connaissons tous les éléments de la pile principale, donc cela peut être interprété comme voyant à l'avenir que nous allons reculer l'élément, nous ne devrions pas faire ce mouvement.
Sample run (les piles sont affichées de bas en haut - donc le premier élément est le bas):
Nous pouvons voir que le pire des cas est lorsque le plus grand élément est placé sur le deuxième fond, tandis que les autres sont triés. Dans le pire des cas, nous pouvons voir que l'algorithme est O (n ^ 2).
Le nombre de coups est évidemment minimum pour
n=1
etn=2
comme nous pouvons le voir sur le résultat, et je crois que c'est aussi minimum pour des valeurs plus grandes den
, bien que je ne puisse pas le prouver.Plus d'explications sont dans le code.
la source
4
. Qu'est-ce que cela stocke le deuxième plus grand élément sur le deuxième assistant? Qu'est-ce que ça veut dire?Java -
21290902083142 se déplace sur des baies 55986Le lien idéone .
Le cadre pour garantir que l'algorithme est correct:
L'algorithme réel:
Le testcase:
la source
C / C ++ N'a pas mesuré les mouvements (chevilles: p1, p2, p3) Je ne sais pas comment ajouter du code C ++ qui utilise STL (problème de formatage). Perte de parties de code en raison des formats de balises html dans le code.
Fusionner les données de déplacement (n + m) de p2 et p3 à p1.
la source
hanoi(...)
fonction. De plus, vous avez 2#include
s qui ne se compilent pas. Veuillez poster le code complet.