• Aucun résultat trouvé

I138 Le carré Breton

N/A
N/A
Protected

Academic year: 2022

Partager "I138 Le carré Breton"

Copied!
6
0
0

Texte intégral

(1)

I138 Le carré Breton

Solution proposée par Régis Schoonheere

En réponse au problème du carré breton, je vous propose la solution suivante en 10 coups : 8, 5, 2, 5, 8, 6, 3, 6, 5, 1.

J'ai écrit un programme en C++ qui utilise une fonction récursive de choix d'un mouvement. L'algorithme choisi essaie d'optimiser une quantité que j'ai appelée distance dans le programme et qui n'est pas celle décrite dans l'énoncé mais le nombre minimum de mouvements pour amener une case donnée à être noire sur fond blanc.

Annexe

Programme en langage C++

using namespace std;

#include <vector>

#include <string>

#include <iostream>

#include <math.h>

// Données initiales

int fond[4][4]={{3,2,1,2},{3,2,3,1},{0,0,2,1},{0,0,0,0}};

int coul[4][4]={{0,4,3,4},{0,0,1,3},{1,2,4,3},{1,2,2,1}};

char let[4][4]={{'B','D','O','L'},{'A','H','C','J'},{'I','G','N','K'},{'M','F','E','P'}};

// variables globales

int mini=100; // Nombre mini de mouvements pour arriver au résultat int result[100]; // Sauvegarde des mouvements de chaque niveau int minscore; // Distance minimum atteinte

int nbcoups=0; // Nombre mini de mouvements pour atteindre la distance mini

// Calcul de la distance = nombre mini de mouvements pour atteindre les couleurs de fond et de caractère finales depuis le couleurs ff (fond) et cc

(2)

(caractère)

int dist(int ff,int cc) {

int depf=-ff; // Mouvements pour la couleur de fond if(depf<0)

depf+=4;

int ccf=cc+depf;

if(ccf>4) ccf-=5;

int depc=ccf-1; // Mouvements pour la couleur de caractère if(depc<0)

depc+=5;

return (depf+4*depc);

}

// Fonction récursive de choix d'un mouvement

void place(int f[4][4], int c[4][4], char l[4][4],int sc, int niv) {

int nf[4][4], nc[4][4];

char nl[4][4];;

int lig,col;

if(!sc) // Si score nul, résultat atteint {

if(niv<mini) // Nombre de mouvements inférieur au mini {

mini=niv;

cout << endl << "Solution en " << niv << " coups : ";

for(int i=0;i<niv;i++)

cout << result[i] << " ";

cout << endl;

} return;

}

if(niv>=mini) // Nombre de muvements supérieur au mini, abandon

(3)

return;

if(sc<minscore) // Meilleure distance {

minscore=sc;

nbcoups=niv;

cout << "Score " << sc << " en " << niv << " coups : ";

for(int i=0;i<niv;i++)

cout << result[i] << " ";

cout << endl;

}

else if(sc==minscore && niv<nbcoups) // Même distance mais nombre de coups inférieur {

nbcoups=niv;

cout << "Score " << sc << " en " << niv << " coups : ";

for(int i=0;i<niv;i++)

cout << result[i] << " ";

cout << endl;

}

// calcul des distances pour les 9 déplacements int ibest=-1,best=sc,tscore[9];

for(int i=0;i<9;i++) {

int score=sc;

lig=i/3;

col=i%3;

// Retrancher les distances des 4 cases concernées du score total for(int j=0;j<2;j++)

for(int k=0;k<2;k++)

score-= dist(f[lig+j][col+k],c[lig+j][col+k]);

// Copie des tableaux de lettres et de couleurs memcpy(nf,f,16*sizeof(int));

(4)

memcpy(nc,c,16*sizeof(int));

memcpy(nl,l,16*sizeof(char));

// Mouvement

nf[lig][col]=f[lig+1][col]==3?0:f[lig+1][col]+1;

nf[lig][col+1]=f[lig][col]==3?0:f[lig][col]+1;

nf[lig+1][col+1]=f[lig][col+1]==3?0:f[lig][col+1]+1;

nf[lig+1][col]=f[lig+1][col+1]==3?0:f[lig+1][col+1]+1;

nc[lig][col]=c[lig+1][col]==4?0:c[lig+1][col]+1;

nc[lig][col+1]=c[lig][col]==4?0:c[lig][col]+1;

nc[lig+1][col+1]=c[lig][col+1]==4?0:c[lig][col+1]+1;

nc[lig+1][col]=c[lig+1][col+1]==4?0:c[lig+1][col+1]+1;

nl[lig][col]=l[lig+1][col];

nl[lig][col+1]=l[lig][col];

nl[lig+1][col+1]=l[lig][col+1];

nl[lig+1][col]=l[lig+1][col+1];

// Ajouter les distances des 4 cases au score total for(int j=0;j<2;j++)

for(int k=0;k<2;k++)

score+= dist(nf[lig+j][col+k],nc[lig+j][col+k]);

tscore[i]=score;

}

// Recherche de la meilleure distance while(true)

{

best=sc; // Score maxi autorisé

ibest=-1;

for(int i=0;i<9;i++)

if(tscore[i]<best) // Meilleur score {

best=tscore[i];

ibest=i;

(5)

}

if(ibest<0) // Pas de meilleur score

return;

tscore[ibest]=101; // Supprimer ce mouvement du tableau des scores // Créer les nouveaux tableaux de données pour ce mouvement

lig=ibest/3;

col=ibest%3;

memcpy(nf,f,16*sizeof(int));

memcpy(nc,c,16*sizeof(int));

memcpy(nl,l,16*sizeof(char));

nf[lig][col]=f[lig+1][col]==3?0:f[lig+1][col]+1;

nf[lig][col+1]=f[lig][col]==3?0:f[lig][col]+1;

nf[lig+1][col+1]=f[lig][col+1]==3?0:f[lig][col+1]+1;

nf[lig+1][col]=f[lig+1][col+1]==3?0:f[lig+1][col+1]+1;

nc[lig][col]=c[lig+1][col]==4?0:c[lig+1][col]+1;

nc[lig][col+1]=c[lig][col]==4?0:c[lig][col]+1;

nc[lig+1][col+1]=c[lig][col+1]==4?0:c[lig][col+1]+1;

nc[lig+1][col]=c[lig+1][col+1]==4?0:c[lig+1][col+1]+1;

nl[lig][col]=l[lig+1][col];

nl[lig][col+1]=l[lig][col];

nl[lig+1][col+1]=l[lig][col+1];

nl[lig+1][col]=l[lig+1][col+1];

result[niv]=ibest+1; // Stocker ce mouvement pour ce niveau // Niveau suivant

place(nf,nc,nl,best,niv+1);

} }

int main() {

// Calcul du score initial

(6)

minscore=0;

for(int i=0;i<4;i++)

for(int j=0;j<4;j++) {

minscore+=dist(fond[i][j],coul[i][j]);

}

cout << "Score initial : " << minscore << endl;

// Choisir le premier mouvement place(fond,coul,let,minscore,0);

}

Références

Documents relatifs

Pour ce qui concerne le nombre de coups à effectuer, la somme des valeurs contenues dans le troisième tableau vaut 40; compte tenu du fait que chaque coup opère sur quatre

la distance « couleurs » égale au nombre de mouvements pour que la lettre retrouve l'apparence désirée (noir sur fond blanc, par ex.).. Cette distance ne dépend que du nombre

Problème au sens de problématique scientifique et didactique, problématique scolaire, problème au sens d’énigme, problème reformulé par l’élève dans un

Tout comme pour la courbe dans le cas d’une charge résistive, nous constatons une diminution de plus en plus importante de la tension secondaire en fonction de l’augmentation

Cette phrase montre que Solvay prend appui sur son référentiel de compétences dans son nouvel accord de GPEC pour saisir les différentes sources de compétences : lors de la

o écrire, en respectant les critères d’évaluation, un texte court expliquant l’expression « Voir loin, c’est voir dans le passé », texte qui sera à rendre sur feuille pour

[r]

Une entreprise fabrique un produit chimique dont le coût total journalier de production pour x litres est donné par la fonction C définie pour tout x ∈ (1 ; 50] par C(x) = 0,5x 2 + 2x