Posté par
_Michel _Michel
La solution optimale fait 11 coups, mais elle n'est pas unique!
En effet, il existe exactement 2 solutions, à la symétrie près (presques identiques) :
HDBBHHDHHBG et
HDBBHHDHHGB
Pour être sûr qu'il n'existe pas de meilleure solution, je n'ai vu qu'une façon de faire : les tester toutes ! Mais comme j'ai autre chose à faire que de tester 1+2+4+8+...+2
11=2
12-1 possiblilités, je délègue...
#include <stdio.h>
#define DEP_POSSIBLE_GAUCHE(Tete) ((((Tete)%5) != 4) && (((Map>>((Tete)+1))&1) == 1))
#define DEP_POSSIBLE_DROITE(Tete) \
( \
(((Tete)%5) != 0) \
&& \
( \
( \
((Tete) == 1) \
&& \
((Map&1) == 1) \
) \
|| \
(((Map>>((Tete)-1))&1) == 1) \
) \
)
#define DEP_POSSIBLE_HAUT(Tete) ((((Tete)/5) != 5) && (((Map>>((Tete)+5))&1) == 1))
#define DEP_POSSIBLE_BAS(Tete) \
( \
(((Tete)/5) != 0) \
&& \
( \
( \
((Tete) == 5) \
&& \
((Map&1) == 1) \
) \
|| \
(((Map>>((Tete)-5))&1) == 1) \
) \
)
#define DEP_GAUCHE(Tete) ((Tete) += 1)
#define DEP_DROITE(Tete) ((Tete) -= 1)
#define DEP_HAUT(Tete) ((Tete) += 5)
#define DEP_BAS(Tete) ((Tete) -= 5)
int main ()
{
unsigned long Map;
int TeteBleue, TeteRouge, TeteVerte;
int NbrDeplacement;
unsigned long Suite;
int i;
unsigned long Deplacement;
// 11011
// 11111
// 11111
// 01110 => 110111111111111011100111000100 => 00110111 11111111 10111001 11000100
// 01110
// 00100
Map = 0x37FFB9C4;
// Test de toutes les suites de déplacement, jusqu'à une solution.
for (NbrDeplacement=1; NbrDeplacement<16; NbrDeplacement++) { // Pas plus de 4^15=2^30 suites sinon bug.
printf ("Test des suites de %d déplacement.\n", NbrDeplacement);
for (Suite=0; Suite<(1UL<<(NbrDeplacement*2)); Suite++) { // Il y a 4^NbrDeplacement suites de déplacements
// Test d'une suite de déplacements
//Mise en place des têtes.
TeteBleue = 2;
TeteVerte = (5*2)+2;
TeteRouge = (5*4)+2;
// Réalisation de la suite de déplacements
for (i=0; i<NbrDeplacement; i++) {
if (i==0) {
Deplacement = Suite&3; // Les deux premiers bits
} else {
Deplacement = (Suite>>(2*i))&3;
}
// "Moteur physique"
switch (Deplacement) {
case 0: // Gauche
if (DEP_POSSIBLE_GAUCHE(TeteVerte))
{
DEP_GAUCHE(TeteVerte);
if (DEP_POSSIBLE_GAUCHE(TeteBleue)) {
DEP_GAUCHE(TeteBleue);
}
if (DEP_POSSIBLE_DROITE(TeteRouge)) {
DEP_DROITE(TeteRouge);
}
}
break;
case 1: // Droite
if (DEP_POSSIBLE_DROITE(TeteVerte))
{
DEP_DROITE(TeteVerte);
if (DEP_POSSIBLE_DROITE(TeteBleue)) {
DEP_DROITE(TeteBleue);
}
if (DEP_POSSIBLE_GAUCHE(TeteRouge)) {
DEP_GAUCHE(TeteRouge);
}
}
break;
case 2: // Haut
if (DEP_POSSIBLE_HAUT(TeteVerte))
{
DEP_HAUT(TeteVerte);
if (DEP_POSSIBLE_HAUT(TeteBleue)) {
DEP_HAUT(TeteBleue);
}
if (DEP_POSSIBLE_BAS(TeteRouge)) {
DEP_BAS(TeteRouge);
}
}
break;
case 3: // Bas
if (DEP_POSSIBLE_BAS(TeteVerte))
{
DEP_BAS(TeteVerte);
if (DEP_POSSIBLE_BAS(TeteBleue)) {
DEP_BAS(TeteBleue);
}
if (DEP_POSSIBLE_HAUT(TeteRouge)) {
DEP_HAUT(TeteRouge);
}
}
}
}
// Test de la validité de la suite de déplacements
if ((TeteBleue == (5*4)+1)&&(TeteRouge == (5*4)+3)) {
printf ("Solution trouvée : %u.\n", Suite);
}
}
}
return 0;
}
Note : sans la tabulation (mais oui : pourquoi?), les définitions de macro prennent tout de suite une dimension artistique...