Corrigé de la séance d'exercices 12, Programmation I
Sciences et Technologies du Vivant, Semestre 1

Exercice 1 - Polygones

#include <iostream>
#include "swindow.h"

using namespace std;

struct point {
  int x, y;
};

struct couleur {
  float rouge, vert, bleu;
};

struct polygone {
  point *points;
  int nbr_points;
  
  couleur coul;
  bool ferme;
};

void affiche_polygone(SimpleWindow *w, polygone *p) {
  w->color(p->coul.rouge, p->coul.vert, p->coul.bleu);
  
  for (int i=0; i<p->nbr_points-1; i++)
    w->drawLine(p->points[i].x, p->points[i].y, p->points[i+1].x,
		p->points[i+1].y);
  if (p->ferme)
    w->drawLine(p->points[p->nbr_points-1].x, p->points[p->nbr_points-1].y,
		p->points[0].x, p->points[0].y);
}

int main(int argc, char **argv) {
  polygone losange;
  
  losange.coul.rouge = 1;
  losange.coul.vert = 0;
  losange.coul.bleu = 0;
  
  losange.ferme = true;
  
  losange.nbr_points = 4;
  losange.points = new point[4];
  
  losange.points[0].x = 10;
  losange.points[0].y = 60;
  losange.points[1].x = 100;
  losange.points[1].y = 10;
  losange.points[2].x = 190;
  losange.points[2].y = 60;
  losange.points[3].x = 100;
  losange.points[3].y = 110;

  SimpleWindow window("Polygone", 300, 300);
  window.map();
  window.color(1, 1, 1);
  window.fill();

  affiche_polygone(&window, &losange);

  window.show();

  cout << "Appuyez sur une touche pour continuer..." << endl;
  char a = getchar();

  delete[] losange.points;

  return 0;
}

Exercice 2 - Structures et pointeurs

#include <iostream>

using namespace std;

struct Reponse {
  int age;
  char genre;
  float salaire;
  bool repA, repB, repC;
};

Reponse *init_reponse(int age, char genre, float salaire,
                      bool repA, bool repB, bool repC) {
  Reponse *nouvelle = new Reponse;
  
  nouvelle->age = age;
  nouvelle->genre = genre;
  nouvelle->salaire = salaire;
  nouvelle->repA = repA;
  nouvelle->repB = repB;
  nouvelle->repC = repC;

  return nouvelle;
}

Reponse *reponse_plus_haut_salaire(Reponse **tab, int taille) {
  float plus_haut_salaire = 0;
  Reponse *rep = NULL;

  for (int i=0; i<taille; i++)
    if (tab[i] != NULL) // ne considere que les elements ayant ete initialises
      if (tab[i]->salaire > plus_haut_salaire) {
        plus_haut_salaire = tab[i]->salaire;
        rep = tab[i];
      }

  return rep;
}

int nombre_hommes_plus_de_trente_ans_AB(Reponse **tab, int taille) {
  int nombre = 0;

  for (int i=0; i<taille; i++)
    if (tab[i] != NULL) // ne considere que les elements ayant ete initialises
      if (tab[i]->age >= 30 && tab[i]->genre == 'M' &&
          tab[i]->repA && tab[i]->repB && !(tab[i]->repC))
        nombre++;

  return nombre;
}

float moyenne_salaires_femmes_moins_de_100000(Reponse **tab, int taille) {
  int nbr_personnes = 0;
  float somme = 0;

  for (int i=0; i<taille; i++)
    if (tab[i] != NULL) // ne considere que les elements ayant ete initialises
      if (tab[i]->genre == 'F' && tab[i]->salaire < 100000) {
        nbr_personnes++;
        somme += tab[i]->salaire;
      }

  if (nbr_personnes > 0)
    return somme / nbr_personnes;
  else
    return -1; // retourne -1 s'il n'a trouve personne
}

bool au_moins_une_reponse_oui_partout(Reponse **tab, int taille) {
  for (int i=0; i<taille; i++)
    if (tab[i] != NULL) // ne considere que les elements ayant ete initialises
      if (tab[i]->repA && tab[i]->repB && tab[i]->repC)
        return true;
  
  return false;
}
  
int main(int argc, char **argv) {
  const int nbr_reponses = 20;

  // declaration du tableau de pointeurs sur reponse
  Reponse *sondage[nbr_reponses];

  // initialise le tableau avec des pointeurs sur 'rien', car le tableau
  // est vide, initialement
  for (int i=0; i<nbr_reponses; i++)
    sondage[i] = NULL;

  // initialise les premiers elements du tableau
  sondage[0] = init_reponse(35, 'M', 65000,  false, true,  false);
  sondage[1] = init_reponse(40, 'F', 80000,  false, true,  true);
  sondage[2] = init_reponse(52, 'F', 110000, true,  true,  true);
  sondage[3] = init_reponse(22, 'M', 50000,  false, false, false);
  sondage[4] = init_reponse(45, 'F', 95000,  true,  true,  false);
  
  Reponse *plus_haut_salaire = reponse_plus_haut_salaire(sondage, nbr_reponses);
  cout << "Plus haut salaire: " << plus_haut_salaire->salaire << endl;

  cout << "Nombre d'hommes de plus de 30 ans ayant repondu oui a A et B et non a C: " 
       << nombre_hommes_plus_de_trente_ans_AB(sondage, nbr_reponses) << endl;

  cout << "Salaire moyen des femmes gagnant moins de 100000: " 
       << moyenne_salaires_femmes_moins_de_100000(sondage, nbr_reponses) << endl;

  if (au_moins_une_reponse_oui_partout(sondage, nbr_reponses))
    cout << "Une personne ou plus a repondu oui a toutes les questions." << endl;
  else
    cout << "Personne n'a repondu oui a toutes les questions." << endl;

  // libere la memoire des elements non-vides du tableau
  for (int i=0; i<5; i++)
    delete sondage[i];

  return 0;
}

Exercice 3 - Tableaux à 3 dimensions

#include "swindow.h"
#include <stdio.h>
#include <iostream>

using namespace std;


const int largeur = 200;
const int hauteur = 100;
const int duree = 100;


void efface(bool tab[largeur][hauteur][duree]) {
  for (int t=0; t<duree; t++)
    for (int y=0; y<hauteur; y++)
      for (int x=0; x<largeur; x++)
        tab[x][y][t] = false;
}

void affiche_animation(SimpleWindow *win, bool anim[largeur][hauteur][duree]) {
  for (int t=0; t<duree; t++) {
    win->color(1, 1, 1); // couleur blanche
    win->fill();         // remplit l'arriere-plan de blan
    win->color(0, 1, 0); // couleur verte (pour le rectangle)
    
    for (int y=0; y<hauteur; y++)
      for (int x=0; x<largeur; x++)
        if (anim[x][y][t])
          win->drawPoint(x, y); // dessine le pixel
    
    win->show();                 // affiche les changements a l'ecran
    usleep(10000);               // attend avant d'afficher l'image suivante
  }
}

void dessine_rectangle(bool anim[largeur][hauteur][duree], int taille_x, int taille_y,
		       int x, int y, int temps) {
  for (int j=0; j<taille_y; j++)
    for (int i=0; i<taille_x; i++)
      anim[(x + i) % largeur][(y + j) % hauteur][temps] = true;
}

void anime_rectangle(bool anim[largeur][hauteur][duree], int x_depart,
		     int y_depart, int taille_x, int taille_y, int vitesse_x,
		     int vitesse_y) {
  int pos_x = x_depart;
  int pos_y = y_depart;
  
  for (int t=0; t<duree; t++) {
    dessine_rectangle(anim, taille_x, taille_y, pos_x, pos_y, t);

    // calcule les coordonnees du rectangle a la prochaine image
    pos_x = (pos_x + vitesse_x) % largeur;
    pos_y = (pos_y + vitesse_y) % hauteur;
  }
}

int main(int argc, char **argv) {
  bool animation[largeur][hauteur][duree];
  
  efface(animation);
  anime_rectangle(animation, 5, 5, 10, 10, 4, 1);

  SimpleWindow window("Animation", largeur, hauteur);
  window.map();

  affiche_animation(&window, animation);

  cout << "Appuyez sur une touche pour continuer" << endl;
  char a = getchar();

  return 0;
}

Exercice 4 - Entrelacement de tableaux (*)

    int *entrelacement(int *A, int *B, int taille) {
      int *R = new int[taille * 2];
      for (int i=0; i<taille; i++) {
        R[i * 2] = A[i];
        R[i * 2 + 1] = B[i];
      }

      return R;
    }

Exercice 5 - Éléments en indice (*)

int *indice(int *T, int taille) {
  if (taille % 2 != 0)
    return 0;  // erreur: taille n'est pas pair
  
  int *T2 = new int[taille / 2];
  for (int i=0; i<taille/2; i++) {
    if (T[i*2+1] < taille / 2 && T[i*2+1] >= 0)
      T2[T[i*2+1]] = T[i * 2];
    else
      return 0; // erreur: l'indice est en dehors du tableau
  }
  
  return T2;
}

Exercice 6 - Damier (*)

void damier(int largeur, int hauteur) {
  for (int i=0; i<hauteur * 2 - 1; i++) {
    for (int j=0; j<largeur * 2 - 1; j++)
      if ((i + j) % 2 == 0)
        cout << "#";
      else
        cout << " ";
    cout << endl;
  }
}

Exercice 7 - Triangle creux (*)

void triangle(int lignes) {
  for (int i=0; i<lignes; i++) {
    for (int j=lignes; j>i; j--)
      cout << " ";

    cout << "/";
    if (i < lignes - 1)
      for (int j=0; j<i*2; j++)
        cout << " ";
    else
      for (int j=0; j<i*2; j++)
        cout << "_";
    cout << "\\" << endl;
  }
}

Exercice 8 - Somme et produit des chiffres (*)

    int n = 0;
    int nb_trouves = 0;

    do 
    {
      int somme = 0, produit = 1;
      int n2 = n;

      do
      {
        somme   += (n2 % 10);
        produit *= (n2 % 10);
        n2 /= 10;
      } while (n2 > 0);
      if (s == p)
      {
        cout << n << endl;
        nb_trouves++;
      }

      n++;
    } while(nb_trouves < 20);

Exercice 9 - Suite de Fibonacci (*)

#include <iostream>
#include <math.h>

using namespace std;

int fibonacci(int n) {
  if (n == 0 || n == 1)
    return 1;
  else
    return fibonacci(n-1) + fibonacci(n-2);
}

int main(int argc, char **argv) {
  int n;
  cout << "Suite de Fibonacci" << endl << "Nombre de termes: ";
  cin >> n;

  if (n > 0)
    cout << "F(0) = 1" << endl;
  if (n > 1)
    cout << "F(1) = 1" << endl;
  
  int f_2 = 1;
  int f_1 = 1;
  int f;

  for (int i=2; i<n; i++) {
    f = f_1 + f_2;
    cout << "F(" << i << ") = " << f << ", q = " << float(f) / f_1 << endl;
    f_2 = f_1;
    f_1 = f;
  }

  cout << "Nombre d'or: " << (1 + sqrt(5)) / 2 << endl;

  cout << "Suite recursive:" << endl;

  for (int i=0; i<n; i++)
    cout << "F(" << i << ") = " << fibonacci(i) << endl;

  return 0;
}

Exercice 10 - Nombres parfaits et nombres amicaux (*)

#include <iostream>

using namespace std;

bool parfait(int n) {
  int somme = 0;
  // il n'y a pas de diviseurs de n entre n et n/2
  for (int i = n/2; i>0; i--)
    if (n % i == 0)
      somme += i;

  return (somme == n);
}

bool amicaux(int a, int b) {
  int somme_a = 0;
  for (int i = a/2; i>0; i--)
    if (a % i == 0)
      somme_a += i;

  if (somme_a == b) {
    int somme_b = 0;
    for (int i = b/2; i>0; i--)
      if (b % i == 0)
        somme_b += i;
    if (somme_b == a)
      return true;
  }
  return false;
}

int main(int argc, char **argv) {
  cout << "Nombre parfaits:" << endl;

  for (int i=1; i<1000; i++)
    if (parfait(i))
      cout << i << " est parfait" << endl;

  return 0;
}

Exercice 11 - Nombres romains (*)

int romain_vers_decimal(char * romain)
{
  if (strlen(romain) == 0)
    return 0;

  // teste d'abord toutes les inversions
  if (strlen(romain) >= 2)
  {
    if (romain[0] == 'C') {
      if (romain[1] == 'D') return 400 + romain_vers_decimal(romain + 2);
      if (romain[1] == 'M') return 900 + romain_vers_decimal(romain + 2);
    }
    if (romain[0] == 'X') {
      if (romain[1] == 'L') return 40  + romain_vers_decimal(romain + 2);
      if (romain[1] == 'C') return 90  + romain_vers_decimal(romain + 2);
    }
    if (romain[0] == 'I') {
      if (romain[1] == 'V') return 4   + romain_vers_decimal(romain + 2);
      if (romain[1] == 'X') return 9   + romain_vers_decimal(romain + 2);
    }
  }
  // si aucune des inversions est trouvee, teste les chiffres dans l'ordre
  if (romain[0] == 'M')
    return 1000 + romain_vers_decimal(romain + 1);
  if (romain[0] == 'D')
    return 500 + romain_vers_decimal(romain + 1);
  if (romain[0] == 'C')
    return 100 + romain_vers_decimal(romain + 1);
  if (romain[0] == 'L')
    return 50 + romain_vers_decimal(romain + 1);
  if (romain[0] == 'X')
    return 10 + romain_vers_decimal(romain + 1);
  if (romain[0] == 'V')
    return 5 + romain_vers_decimal(romain + 1);

  return 1 + romain_vers_decimal(romain + 1);
}

Exercice 12 - Recherche par dichotomie (*)

int recherche(int *T, int taille, int v) {
  if (taille == 0)
    return -1;

  int pivot = taille / 2;

  if (v == T[pivot])
    return pivot;
  else if (taille == 1)
    return -1;
  else if (v < T[pivot])
    return recherche(T, pivot, v);
  else {
    int res = recherche(T + pivot + 1, taille - pivot - 1, v);
    if (res == -1)
      return -1;
    else
      return pivot + 1 + res;
  }
}


Retour