



// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
#define NB_RECIPIENTS 4
#define MAX_VOLUME 50
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
typedef struct S_recipient {
int capacite; // Capacité totale du recipient
int volume_ricard; // Volume de ricard présent dans le récipient
} T_recipient;
typedef struct S_transvasement {
T_recipient *src; // Le recipient source // Si NULL alors fontaine
T_recipient *dst; // Le recipient cible // Si NULL alors fontaine
struct S_transvasement *suiv; // Pointe vers le transvasement suivant, NULL si pas de suivant
} T_transvasement;
T_recipient tab_recipient[NB_RECIPIENTS]; // Tableau representant NB_RECIPIENTS récipients
unsigned char buffer[MAX_VOLUME + 1];
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
int mini(int a,int b) // Retourne le min de 2 entiers
{
return(a<b?a:b);
}
int maxi(int a,int b) // Retourne le max de 2 entiers
{
return(a>b?a:b);
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
int get_capacite(T_recipient *recipient) // Retourne la capacité totale d'un récipient
{
return(recipient->capacite);
}
int get_volume_ricard(T_recipient *recipient) // Retourne le volume de ricard présent dans le récipient
{
return(recipient->volume_ricard);
}
int get_libre(T_recipient *recipient) // Quantité de ricard pouvant encore etre versée
{
return(recipient->capacite - recipient->volume_ricard);
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
void suite_transvasement(T_transvasement *suite) // effectue une liste chainée de tranvasements successifs
{
int a;
while (suite) // tant qu'il reste des transvasements a effectuer on continue :)
{
if (suite->src && suite->dst) // transvasement entre 2 recipients
{
a = mini(get_libre(suite->dst),get_volume_ricard(suite->src)); // on determine la quantite de liquide que l'on pourra verser de src -> dst
suite->src->volume_ricard -= a; // on vide la source ...
suite->dst->volume_ricard += a; // ... de la meme quantite que l'on remplit la destination !
}
else if (suite->src) // transvasement entre recipient -> fontaine
suite->src->volume_ricard = 0; // on vide le recipient
else // transvasement entre fontaine -> recipient
suite->dst->volume_ricard = get_capacite(suite->dst); // on remplit le recipient
suite = suite->suiv; // on passe au transvasement suivant
}
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------void kestion5(int n)
{
int a,b;
T_transvasement trans;
T_recipient save_src,save_dst;
if (n==0) // on vient de faire les n transvasements possibles :) ... on note le resultat des volumes des differents recipients dans buffer
{
for (a=0;a<NB_RECIPIENTS;a++)
buffer[tab_recipient[a].volume_ricard]=1;
return;
}
// il reste encore des transvasements a faire ...
for (a=0;a<=NB_RECIPIENTS;a++) // on choisit un recipient source
{
for (b=0;b<=NB_RECIPIENTS;b++) // et un recipient cible ... ensuite on va transvaser et voir ce ke ca donne :)
{
if (a != b) // on evite les transvasements d'un recipient dans lui meme parce que c pas tres efficace :o)
{
if (a==NB_RECIPIENTS) //
{ // Tout ce micmac
trans.src = NULL; // sert juste a
} // initialiser la
else // structure trans
{ // avec une source
trans.src = &tab_recipient[a]; // (NULL si fontaine)
save_src.capacite = tab_recipient[a].capacite; // et une destination
save_src.volume_ricard = tab_recipient[a].volume_ricard;// (NULL si fontaine)
} // et le pointeur sur
if (b==NB_RECIPIENTS) // le transvasement suivant
{ // a NULL pour ne faire
trans.dst = NULL; // qu'un transvasement par etape
} //
else //
{ //
trans.dst = &tab_recipient[b]; //
save_dst.capacite = tab_recipient[b].capacite; //
save_dst.volume_ricard = tab_recipient[b].volume_ricard;//
} //
//
trans.suiv = NULL; //
suite_transvasement(&trans); // Ensuite on appelle la fonction suite_transvasement() avec la structure qu'on vient d'initialiser
kestion5(n-1); // Le transvasement a eut lieu ... on passe a un autre ... recursivite powaaa !
if (trans.src) //
{ // Ici on est revenu de l'appel de fonction kestion5() !
tab_recipient[a].capacite = save_src.capacite; // C'est donc que l'on est tombé sur un etat blokant ou k'on est a la fin ... on a fait tous
tab_recipient[a].volume_ricard = save_src.volume_ricard;// les transvasements possible dans "une direction" ... on va revenir une etape en arriere
} // et explorer les autres possibilites
if (trans.dst) //
{ // Et pour revenir une etape en arriere comme si il s'etait rien passé on restaure
tab_recipient[b].capacite = save_dst.capacite; // la table des récipients a la valeur qu'elle avait avant l'appel a kestion5()
tab_recipient[b].volume_ricard = save_dst.volume_ricard;// Du coup le programme n'y voit que du feu :) ... C fou quand meme le backtracking :-P
} //
}
}
}
return;
}


)


