Département d'Informatique
IUP1 GMI 2002/2003
Algorithmique & Programmation
Corrigé du Contrôle Continu du
Mardi 17 décembre







Programme de test : domino.c

I   Dominos (définition)

/* ------ définition du type des dominos ------- */

typedef struct { int val_inf; int val_sup; } domino;
/* un domino est défini par 2 valeurs : val_inf et val_sup telles que val_inf <= val_sup */

domino cons_domino(int val1, int val2)
     /* construction d'un domino à partir de 2 valeurs val1 et val2 */
     /* pre-conditions : 0 <= val1 <= 6 && 0 <= val2 <= 6 */
{
  domino D; /* résultat */

  if(val1<=val2) 
   {
     D.val_inf = val1;
     D.val_sup = val2;
   }
  else
   {
     D.val_inf = val2;
     D.val_sup = val1;
   }
  return D;
}

int val_inf(domino D) /* la plus petite des 2 valeurs d'un domino */
{
 return D.val_inf;
}

int val_sup(domino D) /* la plus grande des 2 valeurs d'un domino */
{
 return D.val_sup;
}

int points_domino(domino D) /* nombre de points noirs d'un domino  */
{
  return val_inf(D)+val_sup(D);
}

domino premier_domino(int n)
     /* le premier domino de la table ayant n points noirs */
     /* pré-condition : 0 <= n <= 12 */
{
  domino D_prem; /* résultat */

  if(n<6) 
    D_prem = cons_domino(0,n);
  else
    D_prem = cons_domino(n-6,6);

  return D_prem;
}

domino suiv_domino(domino D)
     /* domino suivant dans la table */
     /* pré-condition: D n'est pas le double six (6-6) */
{
  domino D_suiv; /* résultat */
  int total = points_domino(D); /* nombre de points noirs du domino D */

  if(val_sup(D)-val_inf(D)<=1) /* si D est le dernier domino ayant (total) points noirs */
    D_suiv = premier_domino(total+1); /* on construit le 1er domino ayant (total+1) points */
  else /* sinon */
    D_suiv = cons_domino(val_inf(D)+1,val_sup(D)-1); /* on construit le prochain domino */
     
  return D_suiv;  
}

int compte_domino(int n)
     /* nombre de dominos ayant n points noirs */
{
  domino D; /* prend pour valeurs les dominos ayant n points noirs */
  int r=0;  /* compteur du nombre de dominos ayant n points noirs (initialement 0) */

  if(n>=0 && n<=12)
    {
      D = premier_domino(n); /* on construit le premier domino ayant n points noirs */
      do
        {
        r++;                /* on compte un domino de plus */
        D = suiv_domino(D); /* on passe au domino suivant dans la table */
        }
      while (points_domino(D)==n);  /* tant qu'il reste des dominos à n points */
    }

  return r;
}

II   Dominos (utilisation)

/* -- définition du type des booléens -- */

typedef int bool;
#define true 1
#define false 0

bool chainable2(domino D1,domino D2) /* teste si D1 et D2 sont chainables */ 
{
  /* il faut et il suffit que D1 et D2 aient au moins une valeur commune */
  return (val_inf(D1)==val_inf(D2) || val_inf(D1)==val_sup(D2)
       || val_sup(D1)==val_inf(D2) || val_sup(D1)==val_sup(D2));
} 

bool chainable3(domino D1,domino D2,domino D3)
     /* teste si D1, D2 et D3 sont chainables */ 
     /* pré-condition: D1, D2 et D3 sont tous différents */
{
  bool r; /* résultat */
  domino D1_= D1, D2_= D2, D3_= D3; /* copies de D1, D2 et D3 */

  if(chainable2(D2_,D3_)) /* si on peut chainer D2 et D3 */
    {
      /* on échange D3 avec D1 pour se ramener au cas D1 et D2 chainables */
      domino D;
      D = D3_;
      D3_ = D1_;
      D1_ = D; 
    }  
  if(chainable2(D1_,D3_)) /* si on peut chainer D1 et D3 */
    {
      /* on échange D3 avec D2 pour se ramener au cas D1 et D2 chainables */
      domino D;
      D = D3_;
      D3_ = D2_;
      D2_ = D; 
    }
  if(!chainable2(D1_,D2_)) /* si on n'a pas trouvé 2 dominos chainables parmi les 3 */

    r=false; /* le résultat est faux */

  else /*  si D1 et D2 sont chainables */
    {
      /* on construit un début de chaine */      
      domino D; /* le domino dont les valeurs sont les extrémités de la chaine */

      if(val_inf(D1_)==val_inf(D2_)) 
        D = cons_domino(val_sup(D1_),val_sup(D2_));
      if(val_inf(D1_)==val_sup(D2_)) 
        D = cons_domino(val_sup(D1_),val_inf(D2_));
      if(val_sup(D1_)==val_inf(D2_)) 
        D = cons_domino(val_inf(D1_),val_sup(D2_));
      if(val_sup(D1_)==val_sup(D2_)) 
        D = cons_domino(val_inf(D1_),val_inf(D2_));

      /* le résultat est vrai si D3 peut être ajouté au début de chaine ou bien 
         si D3 a 2 valeurs identiques et D3 peut être chainé avec D1 (ou D2) */
      r = chainable2(D3_,D) || (val_inf(D3_)==val_sup(D3_) && chainable2(D1_,D3_));
    }
 
 return r;  
} 


This document was translated from LATEX by HEVEA.