TD 2 : affectations, instructions conditionnelles#

Exercice 1 : affectations

Voici un fragment de programme Échange. On suppose que les variables entières n1 et n2 ont été préalablement déclarées et initialisées:

n1 = n2;
n2 = n1;
  1. En première lecture, que fait ce fragment de programme?

    BEGIN SOLUTION

    D’après son nom, le fragment de programme devrait échanger les valeurs de n1 et n2.

    END SOLUTION

  2. Exécutez le fragment de programme pas à pas avec comme valeurs initiales 5 et 7 pour les variables n1 et n2 respectivement. Obtient-on à la fin les valeurs attendues dans ces variables ?

    BEGIN SOLUTION

    Exécution pas à pas : on indique les valeurs des variables à chaque étape :

    instruction

    n1

    n2

    7

    4

    n1 = n2;

    4

    4

    n2 = n1;

    4

    4

    On n’obtient pas les valeurs que l’on souhaiterait.

    END SOLUTION

  3. Modifiez le programme pour qu’il réponde à ce qui est attendu. Seules des déclarations de variables et des affectations sont nécessaires pour cela.

    BEGIN SOLUTION

        temporaire = n2;
        n2 = n1;
        n1 = temporaire;
    

    Exécution pas à pas :

    instruction

    n1

    n2

    temporaire

    int n1, n2, temporaire;

    ?

    ?

    ?

    n1 = 7;

    7

    ?

    ?

    n2 = 4;

    7

    4

    ?

    temporaire = n2;

    7

    4

    4

    n2 = n1;

    7

    7

    4

    n1 = temporaire;

    4

    7

    4

    Cette fois on a bien échangé les valeurs de n1 et n2.

    END SOLUTION

Exercice 2 : conditionnelles

En relisant votre cours après l’amphi, vous avez appris les opérations sur les entiers ainsi que les opérations booléennes. Cela vous sera utile dans cet exercice. On suppose que l’on a déjà déclaré et initialisé une variable n de type entier. On veut diviser \(n\) par \(2\) s’il est pair et lui enlever \(1\) s’il est impair. Écrivez les quelques lignes d’instructions correspondantes.

BEGIN SOLUTION

En C++, si n et k sont des entiers, alors n/k est le quotient de la division euclidienne de n par k, et n%k est le reste de la division euclidienne de n par k (voir Cours 2, . Les instructions demandées sont donc :

    if (n % 2 == 0) {
      n = n/2;
    } else {
      n = n-1;
    }

END SOLUTION

Exercice 3 : conditionnelles, fonctions

Dans cet exercice (et les suivants), vous préciserez le nom, l’entrée et la sortie de vos programmes comme dans l’exemple suivant :

// Programme produit
// Entrée: deux entiers a et b de type int
// Sortie: le produit de a et b stocké dans une variable p
int p;
p = a*b;

Si vous vous sentez à l’aise, ou lorsque cela est demandé, mettez votre programme sous la forme d’une fonction :

int produit(int a, int b) {
    return a*b;
}

Lors de la fin d’un semestre dans une Université X, les enseignants sont amenés à calculer la moyenne générale des notes de physique et de mathématiques selon une règle précise : la meilleure note des trois épreuves de mathématiques est comptée coefficient 3, et la meilleure note des deux épreuves de physique est comptée coefficient 2; les autres notes ne comptent pas.

Un enseignant est chargé de concevoir un algorithme prenant en entrée les trois notes de mathématiques et les deux notes de physique, et donnant la moyenne générale suivant la règle énoncée ci-dessus.

  1. Spécifiez et écrivez un algorithme max2 qui, étant donnés deux nombres réels a et b (qu’on suppose déjà déclarés et initialisés), calcule le plus grand des deux et met le résultat dans une variable m.

    BEGIN SOLUTION

    // Programme max2
    // Entrées: deux nombres réels a et b
    // Sortie: le maximum de a et b
    float m;
    if (a < b) {
        m = b;
    } else {
        m = a;
    }
    

    END SOLUTION

  2. Transformez cet algorithme en une fonction nommée max2 pour pouvoir par la suite calculer le maximum de deux nombres avec un appel à la fonction, par exemple max2(7,5).

    BEGIN SOLUTION

    float max2(float a, float b){
        if (a < b) {
            return b;
        } else {
            return a;
        }
    }
    

    END SOLUTION

  3. De même, étant donnés trois nombres réels, donnez un algorithme calculant le plus grand des trois (dans une variable m). On pourra utiliser la fonction max2(a,b).

    BEGIN SOLUTION

    // Programme max3
    // Entrées: trois nombres réels a, b et c
    // Sortie: le maximum de a, b et c
    float m;
    if (a <= c and b <= c) {
        m = c;
    } else if (a <= b) {  // ici, on sait que c n'est pas le maximum
        m = b;
    } else {     // ici, on sait que c n'est pas le maximum et a > b
        m = a;
    }
    

    Variante en utilisant la fonction max2:

    // Entrées: trois nombres réels a, b et c
    // Sortie: le maximum de a, b et c
    float m = max2( a, max2(b, c) );
    

    END SOLUTION

  4. \(\clubsuit\) Transformer cet algorithme en fonction.

    BEGIN SOLUTION

    float max3(float a, float b, float c) {
        if (a <= c and b <= c) {
            return c;
        } else if (a <= b) {
            return b;
        } else {
            return a;
        }
    }
    

    Variante en utilisant la fonction max2:

    float max3(float a, float b, float c) {
        return max2( a, max2(b, c) );
    }
    

    END SOLUTION

  5. Spécifiez et donnez un algorithme qui prend en entrée trois notes de mathématiques, puis deux notes de physique, et calcule la moyenne selon la règle spécifiée.

    BEGIN SOLUTION

    // Programme moyenne
    // Entrées: m1, m2, m3: les notes de math,
    //         p1, p2: les notes de physique
    // Sortie: la moyenne
    float moyenne = (max3(m1, m2, m3) * 3 + max2(p1, p2) * 2) / 5;
    

    END SOLUTION

  6. \(\clubsuit\) Transformez cet algorithme en fonction.

    BEGIN SOLUTION

    float moyenne(float m1, float m2, float m3, float p1, float p2){
        return (max3(m1, m2, m3) * 3 + max2(p1, p2) * 2) / 5;
    }
    

    Si on a déclaré les fonctions max2 et max3 commen renvoyant un float et non un int, il faut écrire /5.0 ci-dessus, sinon on a une division entière (quotient) et pas un calcul exact de la moyenne.

    END SOLUTION

Exercice 4 : rendu de monnaie

On considère une machine qui distribue des sucreries. Le problème consiste à écrire le programme qu’elle exécute pour rendre la monnaie sur une somme, à l’aide de pièces de 50 centimes, 20 centimes, 10 centimes et 5 centimes d’euro, de façon à minimiser le nombre de pièces rendues sachant que l’on connaît le prix et la somme donnée par le client. On suppose que les sommes sont données en centimes d’euro, qu’il n’y a pas de risque de pénurie de pièces de monnaie, et que les prix sont un multiple de 5 centimes. Par exemple si le prix à payer est de 110 centimes et que le client a donné 200 centimes, il faut lui rendre 1 pièce de 50 centimes et 2 pièces de 20 centimes.

  1. Quelles sont les entrées / sorties du problème ?

    BEGIN SOLUTION

    // Entrées : la somme due (prix) et la somme donnée (somme),
    //     des entiers divisibles par 5
    // Sorties : le nombre de pièces de 50, 20, 10 et 5 centimes
    //     à rendre (npieces50, npieces20, npieces10, npieces5).
    

    END SOLUTION

  2. Écrivez un programme pour résoudre le problème. On pourra supposer que les variables prix et somme contiennent respectivement le prix et la somme donnée par le client. À la fin du programme, la variable npieces50 devra contenir le nombre de pièces de cinquante centimes à rendre, et de même pour les variables npieces20, npieces10 et npieces5.

    Note : avec ce que vous avez appris, vous ne pouvez pas encore écrire une fonction pour ce problème (pourquoi?).

    BEGIN SOLUTION

    int a_rendre;
    a_rendre = somme - prix;
    npieces50 = a_rendre / 50;
    a_rendre   = a_rendre % 50;
    npieces20 = a_rendre / 20;
    a_rendre = a_rendre % 20;
    npieces10 = a_rendre / 10;
    a_rendre = a_rendre % 10;
    npieces5 = a_rendre / 5;
    

    On remarque qu’on n’a pas calculé le reste par 5 : on sait qu’il est nul car d’après l’énoncé, les prix sont multiples de 5.

    END SOLUTION

  3. \(\clubsuit\) Comment gérer un nombre limité de pièces en réserve dans la caisse de la machine?

Exercice 5 : \(\clubsuit\) pierre-feuille-ciseaux

Héloïse et Gabriel veulent jouer à pierre-feuille-ciseaux, mais, têtes en l’air, ils ne se souviennent jamais de qui bat quoi.

  1. On numérote les joueurs par \(1\) et \(2\), et on représente un choix par un entier: \(1\) pour une pierre, \(2\) pour une feuille, et \(3\) pour les ciseaux. On suppose que les variables choix1 et choix2 ont été déclarées et initialisées respectivement avec les choix du joueur \(1\) et \(2\). Écrivez un programme dont la sortie, stockée dans une variable gagnant contienne le numéro du joueur gagnant (ou zéro si égalité).

    BEGIN SOLUTION

    	// Entrées : choix1 et choix2
    	int gagnant;
    	if (choix1 == choix2) {
    		gagnant = 0;
    	} else if ( (choix1 == 1 and choix2 == 2)
    	         or (choix1 == 2 and choix2 == 3)
    	         or (choix1 == 3 and choix2 == 1) ) {
    		gagnant =  2;
    	} else {
    		gagnant =  1;
    	}
    

    END SOLUTION

  2. Transformez votre programme sous forme d’une fonction.

    BEGIN SOLUTION

    int gagnant (int c1, int c2) {
    	if (c1 == c2) {
    		return 0;
    	} else if ( (c1 == 1 and c2 == 2)
    	         or (c1 == 2 and c2 == 3)
    	         or (c1 == 3 and c2 == 1) ) {
    		return 2;
    	} else {
    		return 1;
    	}
    }
    

    END SOLUTION

  3. Même chose en représentant un choix par un caractère (type char): “p” pour pierre, “f” pour feuille, “c” pour ciseaux.

    BEGIN SOLUTION

    int gagnant_char (char c1, char c2) {
    	if (c1 == c2) {
    		return 0;
    	} else if ( (c1 == 'p'  and c2 == BEGIN'f')
                 or (c1 == 'f' and c2 == 'c')
                 or (c1 == 'c' and c2 == 'p')  ) {
    		return 2;
    	} else {
    		return 1;
    	}
    }
    

    END SOLUTION

  4. \(\clubsuit\clubsuit\) Même chose en utilisant un type enum (hors programme).

    BEGIN SOLUTION

    int gagnant_char (char c1, char c2) {
    	if (c1 == c2) {
    		return 0;
    	} else if ( (c1 == 'p'  and c2 == BEGIN'f')
                 or (c1 == 'f' and c2 == 'c')
                 or (c1 == 'c' and c2 == 'p')  ) {
    		return 2;
    	} else {
    		return 1;
    	}
    }
    

    END SOLUTION

Vous avez fini la feuille? Regardez les exercices du Projet Euler1, une série de défis, de difficulté croissante, mêlant mathématiques, algorithmique, et programmation. Chaque problème possède une unique solution qu’il s’agit de découvrir par soi-même. Le Problème 19 aborde les thématiques de cette semaine.


1

http://projecteuler.net/; voir http://submoon.freeshell.org/fr/sphinx/euler.html pour les énoncés en français.